Skip to content

什么是集合?

Rust 集合(Collection)是标准库中内置的一些数据结构

  • Vector: 类似 C 语言中动态分配内存的数组
  • String: 类似 C 语言中动态分配内存的字符数组
  • HashMap: 类似 JS 中的 Object 对象, Python 中的 Dict
  • Slice: 之前已经学习过的切片类型

Vector

一种连续的可增长数组类型, 写成 Vec<T> 它是 vector 的缩写

创建 Vector

创建 vector 有两种方式, 通过 new 方法或者 vec!

rust
fn main() {
    // 利用宏创建 Vector 并填充数据
    let array = vec![1, 3, 5, 7, 9];

    // 索引从0开始
    println!("array[0] = {}", array[0]);
    println!("array[1] = {}", array[1]);
}
rust
fn main() {
    // 先不用管这个类型 Vec<i32>, 只需要注意:
    // 这样声明的话, 编译器无法推导类型, 必须要
    // 手动注明类型(因为没有存数据,所以无法推导数据类型)
    let array: Vec<i32> = Vec::new();
}

遍历元素

rust
fn main() {
    let array = vec![1, 3, 5, 7, 9];
    let len = array.len();

    let mut index = 0;
    while index < len {
        println!("array[{}] = {}", index, array[index]);
        index += 1;
    }
}
rust
fn main() {
    let array = vec![1, 3, 5, 7, 9];

    for item in array.iter() {
        println!("item: {}", item);
    }
}
rust
// 三种迭代形式文档: https://rustwiki.org/zh-CN/std/iter/index.html#%E4%B8%89%E7%A7%8D%E8%BF%AD%E4%BB%A3%E5%BD%A2%E5%BC%8F
fn main() {
    let array = vec![1, 3, 5, 7, 9];
    let iter  = array.into_iter();

    for (item, index) in iter.enumerate() {
        println!("array[{}] = {}", index, item);
    }
}

查找数据

rust
fn main() {
    let array = vec![1, 3, 5, 7, 9];

    // 获取第一个元素/最后一个元素
    // 返回一个 Option 枚举
    let last = array.last();    // array[0]
    let first = array.first();  // array[len - 1]
    println!("first: {:?}", first.unwrap());
    println!("last:  {:?}", last.unwrap());

    // 二分查找
    // 返回一个 Result 枚举包括的目标值的 index
    // 没有找到值就是 None
    let item_5 = array.binary_search(&5);
    println!("item_5: {:?}", item_5.unwrap());
}

添加数据

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

    // 获取数组长度
    println!("{:?}", v.len()); // 3

    // 在指定位置插入元素
    v.insert(2, 5);
    println!("{:?}", v);       // [1, 3, 5, 7]
    println!("{:?}", v.len()); // 4

    // 在结尾插入元素
    v.push(9);
    println!("{:?}", v);       // [1, 3, 5, 7, 9]
    println!("{:?}", v.len()); // 5
}

移除数据

rust
fn main() {
    let mut v = vec![1, 3, 5, 7, 9];

    // 移除最后一个元素
    // 返回被移除的值 Option 枚举
    let ret = v.pop();
    println!("pop: {}", ret.unwrap()); // 9
    println!("{:?}", v);               // [1, 3, 5 ,7]

    // 移除指定位置元素
    // 返回被移除的值
    let ret = v.remove(2);
    println!("remove: {}", ret); // 5
    println!("{:?}", v);         // [1, 3, 7]

    // 清空所有元素
    v.clear();
    println!("{:?}", v); // []

    // 判断 Vector 是否为空
    let is_empty = v.is_empty();
    println!("is_empty: {}", is_empty); // true
}

String

什么是字符串

学过C的都知道字符串的本质就是字符数组, 但是和C不同的是, Rust的字符串对象是使用 UTF-8 编码的, 而且封装过的 struct 内置了很多有用的方法

创建字符串

rust
fn main() {
    // 创建字符串, 然后往字符串中添加一些字符
    let mut s1 = String::new();
    s1.push_str("hello world");
    println!("s1:{}", s1);

    // 直接创建字符串
    let s2 = String::from("Hello World");
    println!("s2:{}", s2);

    // 创建字符串切片然后转字符串对象
    let s3 = "hello-world";
    s3.to_string();
    println!("s3:{}", s3);
}

拼接字符串

rust
fn main() {
    let mut str = String::from("str");

    // 1.传入一个 字符串slice, 拼接到字符串对象末尾
    str.push_str("-push_str");
    println!("1: {}", str);

    // 2.传入一个单独的字符, 拼接到字符串对象的末尾
    str.push('c');
    println!("2: {}", str);

    // 3.使用 + 拼接字符串
    let s2 = String::from("s2");
    str = str + "-" + &s2;
    println!("3: {}", str);

    // 4.使用 format! 宏格式化字符串
    let s3 = String::from("s3");
    str = format!("{str}-{s3}-other-string");

    println!("4: {}", str);
}

字节/标量值和形簇

推荐阅读了解即可

遍历字符串方法

rust
fn main() {
    let str = String::from("hello");

    for item in str.bytes() {
        // item 是字符对应的 unicode 编码表数字(10进制)
        // 查看unicode 编码表: https://www.charset.org/utf-8
        // 比如: h 是 104
        println!("item: {}", item);
    }

    println!("------------");

    for item in str.chars() {
        // item 是单个字符: h, e, l, l, o
        println!("item: {}", item);
    }
}

HashMap 键值对

rust
// 注意 HashMap 是需要手动导入的
use std::collections::HashMap;

fn main() {
    let mut rgba:HashMap<String, u8>  = HashMap::new();

    // 设置键值对
    rgba.insert(String::from("red"),   100);
    rgba.insert(String::from("green"), 100);
    rgba.insert(String::from("blue"),  100);

    // 根据键, 获取值, 返回一个 Option 枚举
    let red = rgba.get("red").unwrap();
    println!("get-red:{:?}", red); // 100

    // 根据键, 更新值(同样的 key 重新插入就是更新)
    rgba.insert(String::from("red"), 200);
    let red = rgba.get("red").unwrap();
    println!("reset-red:{:?}", red); // 200

    // 如果没有 key 对应的值就插入, 否则忽略
    rgba.entry(String::from("alpha")).or_insert(50);
    rgba.entry(String::from("alpha")).or_insert(80);
    let alpha = rgba.get("alpha").unwrap();
    println!("or_insert:{:?}", alpha); // 50

    // 遍历HashMap
    for (key, val) in &rgba {
        println!("for-in: {key}:{val}");
    }
}

Released under the MIT License.