• rust容器


    标准库提供了常见的容器。包括向量 ( Vector )、映射( HashMap )、集合( HashSet )。

    一、向量Vector

    数组有一个缺点,就是它的长度在编译时就确定了,一旦确定就永不可更改。
    向量是一个长度可变的数组。向量的存储在堆上,因此长度可变。

    Rust在标准库中定义了结构体Vec用于表示向量。

    (一)定义向量
    一维向量
    1.new()创建一个空向量
    语法格式

    let mut instance_name: Vec = Vec::new();
    例子
    let v1: Vec = Vec::new(); // 创建类型为i32的空向量
    
    • 1
    • 2
    • 3

    2.vec!()宏创建向量
    这种方式的创建方法类似于数组的语法。
    它也有3种创建方式。
    (1)创建空向量。需要指定类型。

    let mut vec_marco: Vec = vec![];
    
    • 1

    (2)指定所有元素。可以省略类型。

    let mut vec_marco = vec![1, 2, 3, 4, 5];
    
    • 1

    (3)指定初始值和长度。可以省略类型。

    let mut vec_marco = vec![0; 5];     // 长度为5,元素初始化为0
    
    • 1

    注意,长度可以是变量,这点与数组不同。
    例子

    let len = 10;
    let zero_vec = vec![0; len];
    
    • 1
    • 2

    3.从数组创建向量

    let arr = [1, 2, 3, 4, 5];
    let v = arr.to_vec();
    
    • 1
    • 2

    4.从区间表达式创建向量

    let n = 10;
    let mut v: Vec<_> = (1..=n).collect();
    println!("{:?}", v);
    
    • 1
    • 2
    • 3

    二维向量
    1.使用new()创建空向量。需要指定类型。

    let mut instance_name: Vec> = Vec::new();
    例子
    let v1: Vec> = Vec::new();
    
    • 1
    • 2
    • 3

    2.使用vec!()宏创建向量
    (1)创建空向量。需要指定类型。

    let mut vec_marco: Vec> = vec![];
    
    • 1

    (2)指定所有元素。可以省略类型。

    let mut vec_marco = vec![vec![1, 2, 3, 4, 5], ...];
    
    • 1

    (3)指定初始值和长度。可以省略类型。

    let mut vec_marco = vec![vec![0; 5]; 10];
    例子
    let width = 4;
    let height = 4;
    let mut array = vec![vec![0; width]; height];
    
    • 1
    • 2
    • 3
    • 4
    • 5

    3.从二维数组创建二维向量
    例如

    let s = [
    [0, 0, 1, 0, 0],
    [0, 0, 1, 0, 0],
    [0, 0, 1, 0, 0],
    [0, 0, 1, 0, 0],
    ];
    let s: Vec<_> = s.iter().map(|&e| e.to_vec()).collect();
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    (二)使用向量
    1.获取长度
    len()方法
    例子

    fn main() {
        let v = vec![1, 2, 3];
        println!("{}", v.len());
        let width = 4;
        let height = 4;
        let array = vec![vec![0; width]; height];
        println!("{} {}", array.len(), array[0].len());
    }
    运行结果如下
    3
    4 4
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    2.添加元素
    使用push方法来追加单个元素
    实例

    fn main() {
        let mut vector = vec![1, 2, 4, 8];
        vector.push(16);
        vector.push(32);
        vector.push(64);
        println!("{:?}", vector);
        let mut arr: Vec> = Vec::new();
        arr.push(Vec::new());
        arr.push(vec![]);
        arr[0].push(1);
        println!("{:?}", arr);
    }
    运行结果:
    [1, 2, 4, 8, 16, 32, 64]
    [[1], []]
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

    使用append方法用于将一个向量拼接到另一个向量的尾部
    实例

    fn main() {
        let mut v1: Vec = vec![1, 2, 4, 8];
        let mut v2: Vec = vec![16, 32, 64];
        v1.append(&mut v2);
        println!("{:?}", v1);
    }
    运行结果:
    [1, 2, 4, 8, 16, 32, 64]
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    2.删除元素
    使用remove()删除元素
    remove() 方法移除并返回向量中指定的下标索引处的元素,将其后面的所有元素移到向左移动一位。

    fn main() {
        let mut v = vec![10,20,30];
        v.remove(1);
        println!("{:?}",v);
    }
    运行结果如下
    [10, 30]
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    使用drain()删除指定范围
    从vector批量删除指定范围,并以迭代器的形式返回所有移除的元素。如果迭代器在被完全消耗之前被丢弃,它会丢弃剩余的已删除元素。

    let mut v = vec![1, 2, 3];
    let u: Vec<_> = v.drain(1..).collect();
    assert_eq!(v, &[1]);
    assert_eq!(u, &[2, 3]);
    // 全范围清除vector,就像 `clear()` 一样
    v.drain(..);
    assert_eq!(v, &[]);
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    clear
    删除所有元素

    let mut v = vec![10,20,30];
    v.clear();
    println!("{:?}",v);
    
    • 1
    • 2
    • 3

    pop()
    从vector中删除最后一个元素并返回它; 如果它为空,则返回 None。
    如果您想弹出第一个元素,请考虑改用 VecDeque::pop_front。

    let mut vec = vec![1, 2, 3];
    assert_eq!(vec.pop(), Some(3));
    assert_eq!(vec, [1, 2]);
    
    • 1
    • 2
    • 3

    3.获取元素
    因为向量实现了Deref Target=[T],所以向量自动实现了切片的所有方法。
    (1)使用get方法
    get方法根据索引返回对元素或子切片的引用。
    如果给定位置,则返回该位置上的元素的引用,如果越界则返回None。
    如果给定范围,则返回对应于该范围的子切片,如果越界则返回None。
    例子

    let v = vec![10, 40, 30];
    assert_eq!(Some(&40), v.get(1));
    assert_eq!(Some(&[10, 40][..]), v.get(0..2));
    assert_eq!(None, v.get(3));
    assert_eq!(None, v.get(0..4));
    
    • 1
    • 2
    • 3
    • 4
    • 5

    (2)get_mut
    get_mut方法根据索引返回对元素或子切片的可变引用
    如果给定位置,则返回该位置上的元素的可变引用,如果越界则返回None。
    如果给定范围,则返回对应于该范围的可变子切片,如果越界则返回None。
    例子

    let mut x = vec![0, 1, 2];
    if let Some(elem) = x.get_mut(1) {
        *elem = 42;
    }
    assert_eq!(x, &[0, 42, 2]);
    
    • 1
    • 2
    • 3
    • 4
    • 5

    (3)使用[]
    实例

    fn main() {
        let v = vec![1, 2, 4, 8];
        println!("{}", v[1]);
    }
    运行结果:
    2
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    二维向量
    例子

    use std::io;
    fn main(){
        let width = 4;
        let height = 4;
        let mut array = vec![vec![0; width]; height];
        for i in 0..4 {
             let mut buf = String::from("");
             io::stdin().read_line(&mut buf).unwrap();
             array[i] = buf.split_whitespace().map(|s| s.parse().unwrap()).collect();
        }
        println!("{:?}", array);
        array[2][2] = 5;
    	println!("{:?}", array);
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    (4)
    first()
    返回切片的第一个元素; 如果为空,则返回None。
    Examples

    let v = [10, 40, 30];
    assert_eq!(Some(&10), v.first());
    let w: &[i32] = &[];
    assert_eq!(None, w.first());
    
    • 1
    • 2
    • 3
    • 4

    last()
    返回切片的最后一个元素; 如果为空,则返回None。
    Examples

    let v = [10, 40, 30];
    assert_eq!(Some(&30), v.last());
    let w: &[i32] = &[];
    assert_eq!(None, w.last());
    
    • 1
    • 2
    • 3
    • 4

    4.遍历向量
    (1)使用索引

    fn main() {
        let v = vec![100, 32, 57];
        for i in 0..v.len() {
                println!("{}", v[i]);
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    (2)使用向量的引用
    实例

    fn main() {
        let v = vec![100, 32, 57];
        for i in &v {
                println!("{}", i);
        }
    }
    运行结果:
    100
    32
    57
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    实例

    fn main() {
        let mut v = vec![100, 32, 57];
        for i in &mut v {
            *i += 50;
        }
        println!("{:?}", v);
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    (3)使用迭代器
    iter()返回一个只读迭代器

    for num in nums1.iter() {
         print!("{} ", num);
    }
    println!();
    
    • 1
    • 2
    • 3
    • 4

    for num in nums1.iter()
    实际上等价于
    for num in &nums1

    iter_mut()返回一个可写迭代器

    let mut nums1 = [1; 5];
    let mut i = 0;
    for num in nums1.iter_mut() {
         *num = i;
         i += 1;
    }
    println!("{:?}", nums1);
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    for num in nums1.iter_mut()
    实际上等价于
    for num in &mut nums1

    into_iter()返回一个迭代器,但是转让所有权

    let mut nums1 = [1; 5];
    for num in nums1.into_iter() {
        print!("{} ", num);
    }
    println!();
    
    • 1
    • 2
    • 3
    • 4
    • 5

    for num in nums1.into_iter()
    实际上等价于
    for num in nums1

    (4)使用迭代器的enumerate

    let mut nums1 = [1; 5];
    for (pos, v) in nums1.iter().enumerate() {
        println!("nums[{}]={}", pos, v);
    }
    println!("{:?}", nums1);
    for (pos, v) in nums1.iter_mut().enumerate() {
        *v=pos;
        println!("nums[{}]={}", pos, v);
    }
    println!("{:?}", nums1);
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    二维向量
    (1)使用索引

    let mut v = vec![vec![1, 2, 3, 4, 5], vec![3, 9, 8]];
    for i in 0..v.len() {
        for j in 0..v[i].len() {
             println!("{}", v[i][j]);
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    (2)使用引用
    例子

    let s = [
    [0, 0, 1, 0, 0],
    [0, 0, 1, 0, 0],
    [0, 0, 1, 0, 0],
    [0, 0, 1, 0, 0],
    ];
    let mut s: Vec<_> = s.iter().map(|&e| e.to_vec()).collect();
    for row in &s{
        for col in row{
             print!("{} ", col);
        }
        println!();
    }
    for row in &mut s {
        for col in row {
             *col += 1;
             print!("{} ", col);
        }
        println!();
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20

    (3)使用向量的迭代器

    let mut grid = [[0; 5]; 5];
    for row in grid.iter() {
        for col in row.iter() {
             print!("{} ", col);
        }
        println!();
    }
    let mut i = 0;
    for row in grid.iter_mut(){
        for col in row.iter_mut() {
             *col = i;
             i += 1;
             print!("{} ", col);
        }
        println!();
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16

    (4)使用迭代器的enumerate

    let mut grid = [[0; 5]; 5];
    for (i, row) in grid.iter().enumerate() {
        for (j, col) in row.iter().enumerate() {
             print!("{}", col);
        }
        println!()
    }
    for (i, row) in grid.iter_mut().enumerate() {
        for (j, col) in row.iter_mut().enumerate() {
             *col = 1;
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    6.使用contains() 判断向量是否包含某个元素
    如果值在向量中存在则返回 true ,否则返回 false 。

    fn main() {
         let v = vec![10,20,30];
         if v.contains(&10) {
             println!("found 10");
         }
         println!("{:?}",v);
    }
    运行结果如下
    found 10
    [10, 20, 30]
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    7.逆转向量

    reverse
    适当地反转切片中元素的顺序。
    例子
    let mut v = [1, 2, 3];
    v.reverse();
    assert!(v == [3, 2, 1]);
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    二、映射HashMap

    映射表(Map)在其他语言中广泛存在。其中应用最普遍的就是散列映射表(Hash Map)。
    HashMap就是 键值对 的集合。映射表中不允许有重复的键,但允许不同的键有相同的值。

    Rust语言定义了HashMap结构体来表示映射表。
    HashMap是无序的,要想使用有序的Map,可以使用BTreeMap。

    (一)定义映射表
    1.使用new创建空映射表

    let mut instance_name: HashMap = HashMap::new();
    
    • 1

    实例

    use std::collections::HashMap;
    let mut map: HashMap<&str, i32> = HashMap::new();
    let mut map = HashMap::new();//可以省略类型
    
    • 1
    • 2
    • 3

    2.可以从数组初始化HashMap
    例子

    use std::collections::HashMap;
    let solar_distance = HashMap::from([
    ("Mercury", 0.4),
    ("Venus", 0.7),
    ("Earth", 1.0),
    ("Mars", 1.5),
    ]);
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    (二)使用映射表
    1.使用len()获取键值对的个数
    例子

    use std::collections::HashMap;
    fn main() {
         let mut stateCodes = HashMap::new();
         stateCodes.insert("name","简单教程");
         stateCodes.insert("site","https://www.twle.cn");
         println!("size of map is {}",stateCodes.len());
    }
    编译运行结果如下
    size of map is 2
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    2.添加键值对
    使用insert()方法用于插入或更新一个键值对
    如果键已经存在,则更新为新的值,并则返回旧的值。
    如果键不存在则执行插入操作并返回None 。

    例子

    fn main() {
        let mut map = HashMap::new();
        map.insert("color", "red");
        map.insert("size", "10 m^2");
        println!("{}", map.get("color").unwrap());
    }
    运行结果:
    red
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    3.删除指定键值对
    remove()用于从映射表中删除指定的键值对。
    如果键值对存在则返回删除的键值对,返回的数据格式为 (&'a K, &'a V) 。
    如果键值对不存在则返回None

    例子

    use std::collections::HashMap;
    fn main() {
         let mut stateCodes = HashMap::new();
         stateCodes.insert("name","简单教程");
         stateCodes.insert("site","https://www.twle.cn");
         stateCodes.insert("slogn","简单教程,简单编程");
         println!("length of the hashmap {}",stateCodes.len());
         stateCodes.remove(&"site");
         println!("length of the hashmap after remove() {}",stateCodes.len());
    }
    编译运行结果如下
    length of the hashmap 3
    length of the hashmap after remove() 2
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    clear
    清除map,删除所有键值对。
    例子

    use std::collections::HashMap;
    let mut a = HashMap::new();
    a.insert(1, "a");
    a.clear();
    assert!(a.is_empty());
    
    • 1
    • 2
    • 3
    • 4
    • 5

    4.根据键获取相应的值
    使用get()方法获取键相应的值。
    如果值不存在,则返回None 。
    如果值存在,则返回值的一个引用。

    例子

    use std::collections::HashMap;
    fn main() {
         let mut stateCodes = HashMap::new();
         stateCodes.insert("name","简单教程");
         stateCodes.insert("site","https://www.twle.cn");
         println!("size of map is {}",stateCodes.len());
         println!("{:?}",stateCodes);
         match stateCodes.get(&"name") {
             Some(value)=> {
                 println!("Value for key name is {}",value);
              }
              None => {
                  println!("nothing found");
              }
         }
    }
    编译运行结果如下
    size of map is 2
    {"name": "简单教程", "site": "https://www.twle.cn"}
    Value for key name is简单教程
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20

    get_mut
    实例

    use std::collections::HashMap;
    fn main() {
        let mut map = HashMap::new();
        map.insert(1, "a");
        if let Some(x) = map.get_mut(&1) {
            *x = "b";
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    get_key_value
    例子

    use std::collections::HashMap;
    let mut map = HashMap::new();
    map.insert(1, "a");
    assert_eq!(map.get_key_value(&1), Some((&1, &"a")));
    assert_eq!(map.get_key_value(&2), None);
    
    • 1
    • 2
    • 3
    • 4
    • 5

    5.遍历映射表
    每次遍历顺序都是不一样的。
    (1)使用引用

    for (book, review) in &book_reviews {
         println!("{book}: \"{review}\"");
    }
    
    for (book, review) in &mut book_reviews {
        *review = 0;
         println!("{book}: \"{review}\"");
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    (2)使用迭代器
    iter()方法会返回映射表中 键值对的引用组成的无序迭代器。
    迭代器元素的类型为 (&'a K, &'a V) 。
    实例

    use std::collections::HashMap;
    fn main() {
        let mut map = HashMap::new();
        map.insert("color", "red");
        map.insert("size", "10 m^2");
        for p in map.iter() {
            println!("{:?}", p);
        }
    }
    运行结果:
    ("color", "red")
    ("size", "10 m^2")
    迭代元素是表示键值对的元组。
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    iter_mut
    例子

    use std::collections::HashMap;
    let mut map = HashMap::from([
    ("a", 1),
    ("b", 2),
    ("c", 3),
    ]);
    // 更新所有值
    for (_, val) in map.iter_mut() {
         *val *= 2;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    6.是否包含指定的键
    contains_key()方法用于判断映射表中是否包含指定的键值对。
    如果包含指定的键,那么会返回相应的值的引用,否则返回None 。

    例子

    use std::collections::HashMap;
    fn main() {
         let mut stateCodes = HashMap::new();
         stateCodes.insert("name","简单教程");
         stateCodes.insert("site","https://www.twle.cn");
         stateCodes.insert("slogn","简单教程,简单编程");
         if stateCodes.contains_key(&"name") {
             println!("found key");
         }
    }
    编译运行结果如下
    found key
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    7.entry
    entry方法返回键值对
    例子

    use std::collections::HashMap;
    let mut player_stats = HashMap::new();
    fn random_stat_buff() -> u32 {
         42
    }
    player_stats.entry("health").or_insert(100);     // 没有就插入,有就跳过
    player_stats.entry("defence").or_insert_with(random_stat_buff);     //没有就插入,有就跳过
    let stat = player_stats.entry("attack").or_insert(100);     //没有就插入,返回值的引用
    *stat += random_stat_buff();
    player_stats.entry("mana").and_modify(|mana| *mana += 200).or_insert(100);     // 有就加200,没有就插入100
    println!("{:?}", player_stats);
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    8.自定义键类型
    派生Eq和Hash。 我们还必须导出PartialEq。
    例子

    use std::collections::HashMap;
    #[derive(Hash, Eq, PartialEq, Debug)]
    struct Viking {
         name: String,
         country: String,
    }
    impl Viking {
         /// 创建一个新的Viking。
         fn new(name: &str, country: &str) -> Viking {
             Viking { name: name.to_string(), country: country.to_string() }
         }
    }
    // 使用HashMap存储Viking的健康点。
    let vikings = HashMap::from([
    (Viking::new("Einar", "Norway"), 25),
    (Viking::new("Olaf", "Denmark"), 24),
    (Viking::new("Harald", "Iceland"), 12),
    ]);
    // 使用派生的实现来打印Viking的状态。
    for (viking, health) in &vikings {
         println!("{viking:?} has {health} hp");
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22

    9.其他
    keys
    返回一个迭代器,以任意顺序访问所有键。 迭代器元素类型为 &'a K。
    例子

    use std::collections::HashMap;
    let map = HashMap::from([
    ("a", 1),
    ("b", 2),
    ("c", 3),
    ]);
    for key in map.keys() {
         println!("{key}");
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    values
    返回一个以任意顺序访问所有值的迭代器。 迭代器元素类型为 &'a V。
    例子

    use std::collections::HashMap;
    let map = HashMap::from([
    ("a", 1),
    ("b", 2),
    ("c", 3),
    ]);
    for val in map.values() {
         println!("{val}");
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    is_empty
    如果map不包含任何元素,则返回true。
    例子

    use std::collections::HashMap;
    let mut a = HashMap::new();
    assert!(a.is_empty());
    a.insert(1, "a");
    assert!(!a.is_empty());
    
    • 1
    • 2
    • 3
    • 4
    • 5

    根据值排序

    use std::collections::HashMap;
    fn main() {
         let map = HashMap::from([("a", 3), ("c", 1), ("b", 2)]);
         let mut v: Vec<_> = map.iter().collect();
         v.sort_by(|a, b| a.1.cmp(b.1));
         println!("{:?}", v);
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    三、集合HashSet

    HashSet是没有重复值的相同数据类型的值的集合。
    Rust语言标准库std::collections中定义了结构体HashSet用于描述集合。
    HashSet是无序的,要想使用有序的Set,可以使用BTreeSet

    (一)定义集合
    1.new()创建一个空集合
    语法格式如下

    let mut hash_set_name = HashSet::new();
    
    • 1

    2.可以从数组初始化HashSet:

    use std::collections::HashSet;
    let viking_names = HashSet::from(["Einar", "Olaf", "Harald"]);
    
    • 1
    • 2

    (二)使用集合
    1.获取集合的长度len()
    len() 方法用于获取集合的长度,也就是集合中元素的个数。

    范例

    use std::collections::HashSet;
    fn main() {
         let mut languages = HashSet::new();
         languages.insert("Python");
         languages.insert("Rust");
         languages.insert("Ruby");
         languages.insert("PHP");
         println!("size of the set is {}",languages.len());
    }
    编译运行结果如下
    size of the set is 4
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    2.添加元素
    insert() 用于插入一个值到集合中,如果集合中已经存在指定的值,则返回 false ,否则返回 true 。

    例子

    use std::collections::HashSet;
    fn main() {
         let mut languages = HashSet::new();
         languages.insert("Python");
         languages.insert("Rust");
         languages.insert("Ruby");
         languages.insert("PHP");
         languages.insert("Rust"); // 插入失败但不会引发异常
         println!("{:?}",languages);
    }
    编译运行结果如下
    {"Python", "PHP", "Rust", "Ruby"}
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    3.删除集合元素
    remove() 方法用于从集合中删除指定的值。
    删除之前如果值 value 存在于集合中则返回 true ,如果不存在则返回 false 。

    例子

    use std::collections::HashSet;
    fn main() {
         let mut languages = HashSet::new();
         languages.insert("Python");
         languages.insert("Rust");
         languages.insert("Ruby");
         println!("length of the Hashset: {}",languages.len());
         languages.remove(&"Kannan");
         println!("length of the Hashset after remove() : {}",languages.len());
    }
    编译运行结果如下
    length of the Hashset: 3
    length of the Hashset after remove() : 3
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    clear
    删除所有值。
    例子

    use std::collections::HashSet;
    let mut v = HashSet::new();
    v.insert(1);
    v.clear();
    assert!(v.is_empty());
    
    • 1
    • 2
    • 3
    • 4
    • 5

    4.获取元素
    get() 方法用于获取集合中指定值的一个引用。
    如果值 value 存在于集合中则返回集合中的相应值的一个引用,否则返回 None 。

    例子

    use std::collections::HashSet;
    fn main() {
         let mut languages = HashSet::new();
         languages.insert("Python");
         languages.insert("Rust");
         languages.insert("Ruby");
         languages.insert("PHP");
         match languages.get(&"Rust"){
             Some(value)=>{
                  println!("found {}",value);
              }
              None =>{
                  println!("not found");
              }
         }
         println!("{:?}",languages);
    }
    编译运行结果如下
    found Rust
    {"Python", "Ruby", "PHP", "Rust"}
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20

    take
    删除并返回集合中等于给定值的值 (如果有)。
    该值可以是集合值类型的任何借用形式,但是借用形式上的Hash和Eq必须与值类型的那些匹配。
    例子

    use std::collections::HashSet;
    let mut set = HashSet::from([1, 2, 3]);
    assert_eq!(set.take(&2), Some(2));
    assert_eq!(set.take(&2), None);
    
    • 1
    • 2
    • 3
    • 4

    5.遍历集合
    每次遍历顺序都是不一样的。
    (1)使用引用

    for book in &books {
         println!("{book}");
    }
    
    • 1
    • 2
    • 3

    (2)使用迭代器
    iter()方法用于返回集合中所有元素组成的无序迭代器。
    集合没有iter_mut()方法。
    例子

    use std::collections::HashSet;
    fn main() {
         let mut languages = HashSet::new();
         languages.insert("Python");
         languages.insert("Rust");
         languages.insert("Ruby");
         languages.insert("PHP");
         for language in languages.iter() {
             println!("{}",language);
         }
    }
    编译运行结果如下
    PHP
    Python
    Rust
    Ruby
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16

    6.判断集合是否包含某个值
    contains() 方法用于判断集合是否包含指定的值。
    如果值 value 存在于集合中则返回 true ,否则返回 false 。

    例子

    use std::collections::HashSet;
    fn main() {
         let mut languages = HashSet::new();
         languages.insert("Python");
         languages.insert("Rust");
         languages.insert("Ruby");
         if languages.contains(&"Rust") {
             println!("found language");
         }
    }
    编译运行结果如下
    found language
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    7.自定义类型
    派生Eq和Hash。我们还必须导出PartialEq,这将在Eq中隐含在future中。

    use std::collections::HashSet;
    #[derive(Hash, Eq, PartialEq, Debug)]
    struct Viking {
         name: String,
         power: usize,
    }
    let mut vikings = HashSet::new();
    vikings.insert(Viking { name: "Einar".to_string(), power: 9 });
    vikings.insert(Viking { name: "Einar".to_string(), power: 9 });
    vikings.insert(Viking { name: "Olaf".to_string(), power: 4 });
    vikings.insert(Viking { name: "Harald".to_string(), power: 8 });
    for x in &vikings {
         println!("{x:?}");
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    8.其他
    is_empty
    如果集合不包含任何元素,则返回true。
    例子

    use std::collections::HashSet;
    let mut v = HashSet::new();
    assert!(v.is_empty());
    v.insert(1);
    assert!(!v.is_empty());
    
    • 1
    • 2
    • 3
    • 4
    • 5

    union
    访问表示并集的值,即self或other中的所有值,没有重复项。
    例子

    use std::collections::HashSet;
    let a = HashSet::from([1, 2, 3]);
    let b = HashSet::from([4, 2, 3, 4]);
    // 以任意顺序打印1、2、3、4。
    for x in a.union(&b) {
    println!("{x}");
    }
    let union: HashSet<_> = a.union(&b).collect();
    assert_eq!(union, [1, 2, 3, 4].iter().collect());
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    intersection
    访问表示相交的值,即self和other中的值。
    当self和other中存在相等的元素时,生成的Intersection可能会引用其中一个。 如果T包含未通过其Eq实现进行比较的字段,并且可能在两组T的两个相等副本之间保持不同的值,则这可能是相关的。
    例子

    use std::collections::HashSet;
    let a = HashSet::from([1, 2, 3]);
    let b = HashSet::from([4, 2, 3, 4]);
    // 以任意顺序打印2,3。
    for x in a.intersection(&b) {
    println!("{x}");
    }
    let intersection: HashSet<_> = a.intersection(&b).collect();
    assert_eq!(intersection, [2, 3].iter().collect());
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    is_subset
    如果集合是另一个集合的子集,则返回true,即other至少包含self中的所有值。
    例子

    use std::collections::HashSet;
    let sup = HashSet::from([1, 2, 3]);
    let mut set = HashSet::new();
    assert_eq!(set.is_subset(&sup), true);
    set.insert(2);
    assert_eq!(set.is_subset(&sup), true);
    set.insert(4);
    assert_eq!(set.is_subset(&sup), false);
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    is_superset
    如果集合是另一个集合的超集,则返回true,即self至少包含other中的所有值。
    例子

    use std::collections::HashSet;
    let sub = HashSet::from([1, 2]);
    let mut set = HashSet::new();
    assert_eq!(set.is_superset(&sub), false);
    set.insert(0);
    set.insert(1);
    assert_eq!(set.is_superset(&sub), false);
    set.insert(2);
    assert_eq!(set.is_superset(&sub), true);
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
  • 相关阅读:
    LabVIEW创建自定义输入控件、显示控件和自定义类型3
    c++加C#实现android开发
    Java项目:ssm毕业论文管理系统
    新人学习笔记之(变量)
    ArcGIS切片服务获取切片方案xml文件(conf.xml)
    QT之mysql数据库的访问
    vue table组件真对某一列或者整个table做模糊匹配
    一篇适合大一同学的算法学习建议
    Redis-分布式锁
    《痞子衡嵌入式半月刊》 第 79 期
  • 原文地址:https://blog.csdn.net/inxunxun/article/details/132998193