首页 技术杂谈 正文
  • 本文约3752字,阅读需19分钟
  • 287
  • 0

Rust - 集合

摘要

Rust集合,数据管理的瑞士军刀。Vector、String、HashMap —— 你的代码库中的强大工具,让数据存储、检索和操作变得精准而高效。

1、集合(Vector\String\HashMap)

1.1、使用Vector存储多个值

  • Vec,叫做Vector
    • 由标准库提供
    • 可以存储多个值
    • 只能存储相同类型的数据
    • 值在内存中连续存放

1.2、创建Vector

  • Vec::new 函数
let number : Vec<i32> = Vec::new();
  • 使用初始值创建Vec,使用vec!宏(常用方法)
let v = vec![1,2,3];

1.3、更新Vector

  • 向Vector添加元素,使用pust方法
let mut number  = Vec::new();
    number.push(1);
    number.push(2);

1.4、删除Vector

  • 与任何其他struct一样,当离开作用域后
    • 它就被清理了
    • 它所有的元素也被清理掉了

1.5、读取Vector的元素

  • 两种方式可以引用Vector里的值
    • 索引
    • get方法
    let v = vec![1,2,3];
    // 读取里面的值 引用
    let third :&i32 = &v[2];
    println!("读取的值为{}",third);

    // Get方法
    match v.get(2) {
        Some(third)=>println!("值为{}",third),
        None => println!("no value"),
    }

1.6、遍历Vector里的值

  • for循环
    let v = vec![1,2,3];

    // for循环遍历
    for i in &v{
        println!("{}",i);
    }

1.7、String字符串

  • 字符串:就是Byte的集合
  • Rust的核心语言层面,只有一个字符串类型:字符串切片str(或&str)
  • 字符串切片:对存储在其他地方、UTF-8编码的字符串的引用
    • 字符串字面值:存储在二进制文件中,也是字符串切片
  • String类型
    • 来自标准库而不是核心语言
    • 可增长、可修改、也拥有所有权
    • UTF-8编码
  • 其他类型的字符串
    • Rust的标准库还包含了很多其它的字符串类型:例如:OsString、OsStr、CString、CStr
    • String 和 Str 后缀结尾:拥有或借用的变体

1.8、创建一个新的字符串

  • 很多Vec 的操作都可以用于String
  • 方法一:String::new() 函数
  • 方法二:使用初始值创建String
    • to_string()方法,可用于实现了Display trait的类型,包括字符串字面值
    • String::from函数,从字面值创建

fn main() {
    // 通过String::New创建字符串
    let mut s_test = String::new();

    // 方法二
    // to_string
    let data = "hello,world";
    let s = data.to_string();
    let s1 = "New Hello World".to_string();

    //String::from
    let s = String::from("From Hello world");
}

1.9、更新String

  • pust_str()方法:把一个字符串切片附加到String

  • pust()方法:把单个字符附加到String

  • 加号(+) : 连接字符串

    • 使用了类似这个签名的方法 fn add(self,s:&str)->String{}
    • 标准库中的ADD方法使用了泛型
    • 只能把&str添加到String
    • 解引用强制转换
  • fromat!:连接多个字符串


fn main() {
    // 通过String::New创建字符串
    let mut s_test = String::new();

    // 方法二
    // to_string
    let data = "hello,world";
    let s = data.to_string();
    let s1 = "New Hello World".to_string();

    //String::from
    let mut s = String::from("From Hello world");
    // pust_str方法
    s.push_str("in world");
    println!("{}",s);
    // pust方法
    s.push('!');

    // + 拼接字符串
    let s2 = String::from("Hello");
    let s3 = String::from("world");
    // s2 就不能使用了,s3因为是调用的引用,所有s3还保留
    let s4 = s2 + &s3;

    // format!宏拼接字符串
    let s5 = format!("{}-{}",s3,s4);
}

1.10、对String类型按索引的形式进行访问

  • 按索引语法访问String会报错
  • Rust的字符串不支持索引语法

1.11、HashMap

  • HashMap<K,V>
    • 键值对的形式存储数据,一个键(Key)对应一个值(Value)
  • Hash函数:决定如何在内存中存放K和V
  • 标准库对其支持比较少,没有内置的宏来创建HashMap
  • HashMap的数据是存放在heap上
  • HashMap是同构的,在一个HashMap上
    • 所有的K必须是同一种类型
    • 所有的V必须是同一种类型

1.12、创建HashMap

use std::collections::HashMap;

fn main() {
    // 如果不指定类型会报错
    // 要么在定义时指定类型
    // let mut hash_test:HashMap<String,i32> = HashMap::new();
    let mut hash_test = HashMap::new();
    // 手动添加数据
    hash_test.insert("name", "小明");
    // 后面添加的类型必须相同
    //hash_test.insert(123, 123);

}

1.13、另一种创建HashMap方法:collect方法

  • 只能在特定场景使用
  • 在元素类型为Tuple的Vector上使用collect,可以组建一个HashMap
    • 要求Tuple有两个值:一个作为K,一个作为V
    • collect方法可以把数据整合成多种集合类型
use std::collections::HashMap;

fn main() {
    let teams = vec![String::from("Blue"),String::from("yellow")];
    let intial_scores = vec![10,30];
    let scores : HashMap<_,_> =teams.iter().zip(intial_scores.iter()).collect();
}

1.14、HashMap的所有权

  • 对于实现了Copy trait的类型,值会被复制到HashMap中
  • 对于拥有所有权的值,值会被移动,所有权会转移给HashMap
  • 如果把值的引用插入HashMap,值本身不会移动

1.15、访问HashMap的值

  • get方法
    • 参数:K
    • 返回:Option<&v>
use std::collections::HashMap;

fn main() {
    let mut scores =HashMap::new();
    scores.insert(String::from("blue"), 10);
    scores.insert(String::from("yellow"), 50);

    let team_name = String::from("blue");
    let score = scores.get(&team_name);

    match score {
        Some(s) => println!("{}",s),
        None => println!("no exit"),
    };
}

1.16、遍历HashMap

  • for循环
use std::collections::HashMap;

fn main() {
    let mut scores =HashMap::new();
    scores.insert(String::from("blue"), 10);
    scores.insert(String::from("yellow"), 50);

    // 调用的是引用
    for (k,v) in &scores  {
        println!("{},{}",k,v);
    }
}

1.17、更新HashMap

  • HaspMap大小可变
  • 每个K同时只能对应一个V
  • 更新HashMap中的数据
    • K已经存在,对应一个V
    • 替换现有的v
    • 保留现有的V,忽略新的V
    • 合并现有的V和新的V
    • K不存在
    • 添加一堆K,V
use std::collections::HashMap;

fn main() {
    let mut scores =HashMap::new();
    scores.insert(String::from("blue"), 10);
    scores.insert(String::from("yellow"), 50);

    // 替换现有的V,插入的K名称相同,那个原来的值会被替代
    scores.insert(String::from("blue"), 70);
    println!("{:?}",scores);

    // 检查K是否存在,使用entry方法,该方法会判断K中是否存在V,
    // 如果不存在通过or_insert方法插入值
    scores.entry(String::from("blue")).or_insert(90);
    scores.entry(String::from("write")).or_insert(888);
    println!("{:?}",scores);
}

1.18、Hash函数

  • 默认情况下,HashMap使用了加密的Hash函数,可以抵抗DOS
    • 不是可用的最快的Hash算法
    • 但具有更好安全性
  • 可以指定不同的Hasher切换到另一个函数
评论