Rust 核心语言中,只有一种字符串类型:str。字符串 slice,通常以被借用的形式出现 &str
String类型是由标准库提供的,是可增长的、可变的、有所有权的、UTF-8 编码的字符串类型。

新建字符串

  1. let mut s = String::new();

s 是空的字符串呢,可以向其中装载数据。通常字符串会有初始数据,可以使用 to_string方法,能用于任何实现了 Displaytrait 的类型。

  1. let data = "initial contents";
  2. let s = data.to_string();
  3. // 该方法也可直接用于字符串字面值
  4. let s = "initial contents".to_string();
  5. let s = String::from("initial contents");

更新字符串

使用 push_str 和 push 附加字符串

  1. let mut s = String::from("foo");
  2. s.push_str("bar");

push_str 的入参事 slice,不会获取参数的所有权

  1. let mut s = String::from("lo");
  2. s.push('l'); // push 方法用于单独的字符

使用 + 运算符或 format!宏拼接字符串

  1. let s1 = String::from("Hello, ");
  2. let s2 = String::from("world!");
  3. let s3 = s1 + &s2; // 注意 s1 被移动了,不能继续使用

s1 在相加后不再有效的原因,和使用 s2 的引用的原因,与使用 + 运算符时调用的函数签名有关。

  1. fn add(self, s: &str) -> String {

这里,add 调用中使用 &s2 是因为 &String 可以被 强转(coerced)成 &str——Deref 强制转换(deref coercion)。

  1. let s1 = String::from("tic");
  2. let s2 = String::from("tac");
  3. let s3 = String::from("toe");
  4. let s = format!("{}-{}-{}", s1, s2, s3);

索引字符串

在 Rust 中,如果尝试使用索引语法来访问 String 的一部分呢,会出现一个错误。

  1. let s1 = String::from("hello");
  2. let h = s1[0];
  1. $ cargo run
  2. Compiling collections v0.1.0 (file:///projects/collections)
  3. error[E0277]: the type `String` cannot be indexed by `{integer}`
  4. --> src/main.rs:3:13
  5. |
  6. 3 | let h = s1[0];
  7. | ^^^^^ `String` cannot be indexed by `{integer}`
  8. |
  9. = help: the trait `Index<{integer}>` is not implemented for `String`
  10. For more information about this error, try `rustc --explain E0277`.
  11. error: could not compile `collections` due to previous error

Rust 字符串不支持索引

内部表现

String是一个 Vec<u8>的封装。由于 UTF-8 文本与 u8 的对应不一定一致,例如字节、标量值和字形簇。
同时,索引操作预期总是需要常数时间,但是对于 Strinng 不可能保证这样的性能。

字符串 slice

  1. let hello = "Здравствуйте";
  2. let s = &hello[0..4];
  3. // s: Зд

遍历字符串方法

  1. for c in "नमस्ते".chars() {
  2. println!("{}", c);
  3. }
  4. for b in "नमस्ते".bytes() {
  5. println!("{}", b);
  6. }
  7. 224
  8. 164
  9. // --snip--
  10. 165
  11. 135