推荐答案
在 Rust 中,字符串操作主要通过两种类型来实现:String
和 &str
。String
是一个可变的、拥有所有权的字符串类型,而 &str
是一个不可变的字符串切片类型。
常见字符串操作
创建字符串
let mut s = String::new(); // 创建一个空字符串 let s = String::from("hello"); // 从字面量创建字符串 let s = "hello".to_string(); // 将字符串字面量转换为 String
字符串拼接
let s1 = String::from("Hello, "); let s2 = String::from("world!"); let s3 = s1 + &s2; // 使用 + 运算符拼接字符串
字符串切片
let s = String::from("hello"); let slice = &s[0..2]; // 获取字符串的前两个字符
遍历字符串
let s = String::from("hello"); for c in s.chars() { println!("{}", c); }
字符串替换
let s = String::from("hello world"); let new_s = s.replace("world", "Rust"); // 替换字符串中的子串
字符串分割
let s = String::from("hello,world,rust"); let parts: Vec<&str> = s.split(',').collect(); // 按逗号分割字符串
字符串大小写转换
let s = String::from("Hello"); let lower = s.to_lowercase(); // 转换为小写 let upper = s.to_uppercase(); // 转换为大写
本题详细解读
String
和 &str
的区别
String
是一个可变的、拥有所有权的字符串类型,存储在堆上。你可以对其进行修改、追加、删除等操作。&str
是一个不可变的字符串切片类型,通常是对String
或字符串字面量的引用。它不拥有数据,因此不能直接修改。
字符串拼接的注意事项
在 Rust 中,字符串拼接通常使用 +
运算符,但需要注意的是,+
运算符会消耗左边的 String
并返回一个新的 String
。因此,如果你需要多次拼接字符串,使用 format!
宏可能更高效:
let s1 = String::from("Hello"); let s2 = String::from("world"); let s3 = format!("{} {}", s1, s2); // 使用 format! 宏拼接字符串
字符串切片的边界问题
在 Rust 中,字符串切片是基于字节索引的,而不是字符索引。因此,如果你尝试在非 UTF-8 字符边界上进行切片,会导致程序 panic。例如:
let s = String::from("hello"); let slice = &s[0..1]; // 正确 let slice = &s[0..2]; // 正确 let slice = &s[0..3]; // 正确 let slice = &s[0..4]; // 正确 let slice = &s[0..5]; // 正确 let slice = &s[0..6]; // panic,因为超出了字符串的字节范围
字符串遍历
Rust 中的字符串是 UTF-8 编码的,因此遍历字符串时需要使用 chars()
方法,它会返回一个字符迭代器。如果你使用 bytes()
方法,则会返回字节迭代器,这可能不是你想要的。
let s = String::from("hello"); for c in s.chars() { println!("{}", c); // 输出每个字符 } for b in s.bytes() { println!("{}", b); // 输出每个字节 }
字符串替换和分割
Rust 提供了丰富的字符串操作方法,如 replace
和 split
。这些方法都非常直观,但需要注意的是,它们返回的是新的字符串或字符串切片,原始字符串不会被修改。
let s = String::from("hello world"); let new_s = s.replace("world", "Rust"); // 替换字符串中的子串 let parts: Vec<&str> = s.split(' ').collect(); // 按空格分割字符串
字符串大小写转换
Rust 提供了 to_lowercase
和 to_uppercase
方法来转换字符串的大小写。这些方法返回的是新的字符串,原始字符串不会被修改。
let s = String::from("Hello"); let lower = s.to_lowercase(); // 转换为小写 let upper = s.to_uppercase(); // 转换为大写