Rust 核心语言中,只有一种字符串类型:str
。字符串 slice,通常以被借用的形式出现 &str
。String
类型是由标准库提供的,是可增长的、可变的、有所有权的、UTF-8 编码的字符串类型。
新建字符串
let mut s = String::new();
s 是空的字符串呢,可以向其中装载数据。通常字符串会有初始数据,可以使用 to_string
方法,能用于任何实现了 Display
trait 的类型。
let data = "initial contents";
let s = data.to_string();
// 该方法也可直接用于字符串字面值
let s = "initial contents".to_string();
let s = String::from("initial contents");
更新字符串
使用 push_str 和 push 附加字符串
let mut s = String::from("foo");
s.push_str("bar");
push_str 的入参事 slice,不会获取参数的所有权。
let mut s = String::from("lo");
s.push('l'); // push 方法用于单独的字符
使用 + 运算符或 format!宏拼接字符串
let s1 = String::from("Hello, ");
let s2 = String::from("world!");
let s3 = s1 + &s2; // 注意 s1 被移动了,不能继续使用
s1 在相加后不再有效的原因,和使用 s2 的引用的原因,与使用 + 运算符时调用的函数签名有关。
fn add(self, s: &str) -> String {
这里,add 调用中使用 &s2
是因为 &String
可以被 强转(coerced)成 &str
——Deref 强制转换(deref coercion)。
let s1 = String::from("tic");
let s2 = String::from("tac");
let s3 = String::from("toe");
let s = format!("{}-{}-{}", s1, s2, s3);
索引字符串
在 Rust 中,如果尝试使用索引语法来访问 String 的一部分呢,会出现一个错误。
let s1 = String::from("hello");
let h = s1[0];
$ cargo run
Compiling collections v0.1.0 (file:///projects/collections)
error[E0277]: the type `String` cannot be indexed by `{integer}`
--> src/main.rs:3:13
|
3 | let h = s1[0];
| ^^^^^ `String` cannot be indexed by `{integer}`
|
= help: the trait `Index<{integer}>` is not implemented for `String`
For more information about this error, try `rustc --explain E0277`.
error: could not compile `collections` due to previous error
内部表现
String
是一个 Vec<u8>
的封装。由于 UTF-8 文本与 u8 的对应不一定一致,例如字节、标量值和字形簇。
同时,索引操作预期总是需要常数时间,但是对于 Strinng 不可能保证这样的性能。
字符串 slice
let hello = "Здравствуйте";
let s = &hello[0..4];
// s: Зд
遍历字符串方法
for c in "नमस्ते".chars() {
println!("{}", c);
}
न
म
स
्
त
े
for b in "नमस्ते".bytes() {
println!("{}", b);
}
224
164
// --snip--
165
135