Skip to content

8. Rust 集合

8.1 Vector

使用 Vector 可存储多个值。

  • 由标准库提供
  • 可存储多个值
  • 只能存储相同类型的值
  • 值在内存中连续存放

使用 Vec<T> 声明 Vector,使用 Vec::new() 创建空 Vector。

rust
fn main() {
    let v: Vec<i32> = Vec::new();
}

使用 vec! 宏可以从列表创建 Vector。

rust
fn main() {
    let v = vec![1, 2, 3];
}

可以使用引用来访问 Vector 中的元素。

rust
fn main() {
    let v = vec![1, 2, 3];
    let third: &i32 = &v[2];
    println!("The third element is {}", third);
}

可以使用 get() 方法来访问 Vector 中的元素。

rust
fn main() {
    let v = vec![1, 2, 3];
    match v.get(2) {
        Some(third) => println!("The third element is {}", third),
        None => println!("There is no third element."),
    }
}

Vector 也遵循所有权和借用规则,不能在同一个作用域内同时存在可变和不可变引用。

rust
fn main() {
    let mut v = vec![1, 2, 3, 4, 5];
    let first = &v[0];
    v.push(6); // error: cannot borrow `v` as mutable because it is also borrowed as immutable
    println!("The first element is: {}", first);
}

使用 for 循环遍历 Vector。

rust
fn main() {
    let v = vec![100, 32, 57];
    for i in &v {
        println!("{}", i);
    }
}

使用可变引用修改 Vector 中的元素。

rust
fn main() {
    let mut v = vec![100, 32, 57];
    for i in &mut v {
        *i += 50;
    }
}

8.2 Vector 的枚举

可以使用枚举来存储不同类型的值。

rust
enum SpreadsheetCell {
    Int(i32),
    Float(f64),
    Text(String),
}

fn main() {
    let row = vec![
        SpreadsheetCell::Int(3),
        SpreadsheetCell::Text(String::from("blue")),
        SpreadsheetCell::Float(10.12),
    ];
}

8.3 String

Rust 开发者经常会被字符串所困扰:

  • Rust 倾向于暴露可能的错误
  • 字符串数据结构复杂
  • 字符串使用 UTF-8 编码

字符串实际上是 Byte 的集合,提供了一些方法,并能将 Byte 集合转换为文本。

Rust 语言核心层面没有字符串类型,而是使用标准库提供的 String 类型。Rust 核心语言层面只有一种字符串类型,即字符串切片 str(或 &str)。

String 类型是标准库提供的,是一种可获得所有权的、可增长、可修改、堆分配的 UTF-8 编码的字符串类型。

  • 许多 Vec<T> 的操作也适用于 String
  • 可以使用 String::new() 创建空字符串
  • 可以使用 to_string() 方法将字符串切片转换为 String
  • 可以使用 String::from() 方法将字符串切片转换为 String
rust
fn main() {
    let mut s = String::new();
    let data = "initial contents";
    let s = data.to_string();
    let s = String::from("initial contents");
}

使用 push_str() 方法追加字符串切片。

rust
fn main() {
    let mut s = String::from("foo");
    s.push_str("bar");
}

使用 push() 方法追加字符。

rust
fn main() {
    let mut s = String::from("lo");
    s.push('l');
}

使用运算符 + 可以拼接字符串,类似于 fn add(self, s: &str) -> String 方法。

rust
fn main() {
    let s1 = String::from("Hello, ");
    let s2 = String::from("world!");
    let s3 = s1 + &s2;
}
  • 标准库中的 add() 方法使用了泛型
  • 只能将 &str 添加到 String
  • Rust 使用了解引用强制转换(deref coercion)

Rust 会将 &String 转换为 &str,所以 &s2 会被转换为 &s2[..]

使用 format! 宏拼接字符串,不会获取所有权。

rust
fn main() {
    let s1 = String::from("tic");
    let s2 = String::from("tac");
    let s3 = String::from("toe");
    let s = format!("{}-{}-{}", s1, s2, s3);
}

8.4 String 的访问