常见集合(8)

常见集合

1.使用Vector存储列表

  • vector允许我们一个挨着一个地存储一系列数量可变的值

1.1新建vector

1.新建一个空的vector来存储i32类型的值
rust 复制代码
let v: Vec<i32> = Vec::new();
2.新建一个包含初值的vector
  • 为了方便Rust提供了Vec!宏,这个宏会根据提供的值来创建一个新的Vector
rust 复制代码
// 默认推断为i32的数据类型,i32是默认整数类型
let v = vec![1,2,3];

1.2更新vector

  • 向vector增加元素,使用push方法
rust 复制代码
let mut v = Vec::new();
v.push(1);
v.push(2);
v.push(3);

1.3读取vector的元素

  • 读取vector中存储的值有两种方式
    • 索引
    • get方法
rust 复制代码
fn main() {
    let v = vec![1, 2, 3, 4, 5, 6];
    let third: &i32 = &v[2];
    println!("The third element is {third}");

    let third: Option<&i32> = v.get(2);
    match third {
        Some(third) => println!("The third element is {third}"),
        None => println!("There is no third element"),
    }
}
1.使用索引语法或get方法来访问vector中的项
  • 索引语法
    • 索引是从数字0开始的,使用**&**和[ ]会得到一个索引位置元素的引用
    • 越界索引 ,引用一个不存在的元素时Rust会造成panic
  • get方法
    • 使用索引作为参数调用get 方法时,会得到一个可以用于match的Option<&T>
    • 越界索引 ,不会panic ,而是返回None
2.在拥有vector中项的引用的同时向其增加一个元素
  • 注意事项
rust 复制代码
fn main() {
    let mut v = vec![1, 2, 3, 4, 5, 6];
    //引用
    let first = &v[0];
    //在vector的结尾增加新元素时,在没有足够空间将所有元素依次相邻存放的情况下,可能会要求分配新内存并将老的元素拷贝到新的空间中
    v.push(6);
    // 第一个元素的引用就指向了被释放的内存,运行报错
    println!("The first element is: {first}");
}

1.4遍历vector中的元素

1.通过for循环遍历vector的元素
rust 复制代码
let v = vec![110,23,96];
for i in &v{
	println!("{i}")
}
2.遍历vector中元素的可变引用
rust 复制代码
let mut v = vec![300,23,54];
for i in &mut v{
	*i += 50;
}

1.5使用枚举来存储多种类型

rust 复制代码
enum SpreadsheetCell{
	Int(i32),
	Float(f64),
	Text(String),
}
let row = vec![
	SpreadsheetCell::Int(3),
	SpreadsheetCell::Text(String::from("blue")),
	SpreadsheetCell::Float(10.12),
];

1.6丢弃vectorr时也会丢弃其所有元素

  • 类似于任何其他的struct,vector在其离开作用域时会被释放
rust 复制代码
{
	let v = vec![1,2,3,4];
	// do stuff with v
}
//v goes out of scope and is freed here

1.7移除vector的元素

rust 复制代码
fn main() {
    let mut v = vec![1, 2, 3, 4, 5, 6];
    let num: Option<i32> = v.pop();
    match num {
        Some(num) => println!("{num}"),
        None => println!("There is no number"),
    }
    for i in &v {
        print!("{i} "); // 1 2 3 4 5
    }
}

2.使用字符串存储UTF-8编码的文本

  • 字符串是字符的集合

2.1什么是字符串

  • Rust的核心语言中只有一种字符串类型: 字符串 slice str ,通常以被借用的形式出现 &str
  • 字符串(String )类型由Rust标准库提供,而不是编入核心语言 ,它是一种可增长可变可拥有UTF-8编码的字符串类型
  • Rustaceans提及Rust中的"字符串"时,可能指的是Stringstring slice &str类型,而不是其中仅仅一种类型

2.2新建字符串

1.新建一个空的String
rust 复制代码
let mut s = String::new();
2.使用to_string方法从字符串字面值创建String
rust 复制代码
fn main() {
    let data = "initial contents";
    let s = data.to_string();
    println!("{s}");
    //该方法也可直接用于字符串字面值
    let s = "initial contents".to_string();
}
3.使用String::from函数从字符串字面值创建String
  • String::from.to_string最终做了完全相同的工作
rust 复制代码
let s = String::from("initial contents");

2.3更新字符串

  • String的大小可以增加,其内容也可以改变
  • 可以使用 + 运算符或 format! 宏来拼接String值
1.使用 push_str 和 push 附加字符串
  • 可以通过 push_str 方法来附加字符串slice,从而使 String 变长
rust 复制代码
fn main() {
    let mut str = String::from("foo");
    let new_str = "bar";
    str.push_str(new_str);
    println!("new_str is {new_str}"); // new_str is bar
}
  • 使用push将一个字符加入String值中
rust 复制代码
fn main() {
    let mut s = String::from("lo");
    s.push('l');
    println!("{s}"); //lol
}

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

1.使用运算符 + 将两个String值合并到一个新的String值中
rust 复制代码
fn main() {
    let s1 = String::from("Hello, ");
    let s2 = String::from("world");
    let s3 = s1 + &s2;
    println!("{s3}");
    // 注意S1被移动了,不能继续使用
    //println!("{s1}");
}
2.使用 format! 宏
rust 复制代码
let s1 = String::from("tic");
let s2 = String::from("tac");
let s3 = String::from("toe");

//对于复杂的字符串连接,使用format!宏,更加直观
let s = s1 + "-"+ &s2 + "-" + &s3;

let new_s = format!("{s1}-{s2}-{s3}");

2.5索引字符串

  • Rust的字符串不支持索引
  • String是一个Vec< u8>的封装

2.6字符串slice

rust 复制代码
let hello = "Здравствуйте";
let s = &hello[0..4];// Зд

2.7遍历字符串的方法

1.字符
rust 复制代码
for c in "Зд".chars(){
	println!("{c}");// З  д
}
2.字节
rust 复制代码
for b in "Зд".bytes(){
	println!("{b}");//  208  151  208 180

}

3.使用Hash Map存储键值对

  • 允许我们将值与一个特定的键(key)相关联
  • 所有的键必须是相同类型,值必须都是相同类型

3.1新建一个哈希map

rust 复制代码
use std::collections::HashMap;

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

3.2访问哈希map中的值

1.访问哈希map的值
rust 复制代码
use std::collections::HashMap;

fn main() {
    let mut scores = HashMap::new();
    scores.insert(String::from("Blue"), 10);
    scores.insert(String::from("Yellow"), 50);
}
2.访问哈希map的键值对
rust 复制代码
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).copied().unwrap_or(0);
    println!("{score}"); // 10

    for (key, value) in &scores {
        println!("{key}: {value}");
    }
}

3.哈希map和所有权

  • i32实现了Copy trait的类型,其值可以拷贝进哈希map
  • String这种拥有所有权的值,其值将被移动到哈希map会称为这些值的所有者
rust 复制代码
use std::collections::HashMap;
fn main() {
    let field_name = String::from("Favorite color");
    let field_value = String::from("Blue");

    let mut map = HashMap::new();
    map.insert(field_name, field_value);
    // field_name和field_value 移动到哈希map中,将不能使用这个两个绑定
    //println!("The is key:{field_name}");
}

4.更新哈希map

1.覆盖一个值
rust 复制代码
use std::collections::HashMap;
let mut scores = HashMap::new();
scores.insert(String::from("Blue"),10);
scores.insert(String::from("Blue"),25);

println!("{:?}",scores);// {"Blue": 25}
2.只在键没有对应值时插入键值对
  • Entryor_insert 方法在键对应的值存在时就返回这个值的可变引用,如果不存在则将参数作为新值插入并返回新值的可变引用
rust 复制代码
use std::collections::HashMap;
fn main() {
    let mut scores = HashMap::new();
    scores.insert(String::from("Blue"), 5);

    
    scores.entry(String::from("Yellow")).or_insert(50);
    scores.entry(String::from("Blue")).or_insert(50);

    println!("{:?}", scores);// {"Yellow": 50, "Blue": 5}
}
3.根据旧值更新一个值
rust 复制代码
use std::collections::HashMap;
fn main() {
    let text = "hello world wonderful world";
    let mut map = HashMap::new();
    for word in text.split_whitespace() {
        // or_insert方法返回这个键的值的一个可变引用(&mut v)
        let count = map.entry(word).or_insert(0);
        *count += 1;
    }
    println!("{:?}", map); // {"world": 2, "wonderful": 1, "hello": 1}
}
相关推荐
mit6.8243 分钟前
[lc-rs] swap|lev_dist源码
rust
往事随风去8 分钟前
那个让老板闭嘴、让性能翻倍的“黑科技”:基准测试最全指南
后端·测试
李广坤17 分钟前
JAVA线程池详解
后端
调试人生的显微镜24 分钟前
深入剖析 iOS 26 系统流畅度,多工具协同监控与性能优化实践
后端
蹦跑的蜗牛25 分钟前
Spring Boot使用Redis实现消息队列
spring boot·redis·后端
非凡ghost33 分钟前
HWiNFO(专业系统信息检测工具)
前端·javascript·后端
非凡ghost36 分钟前
FireAlpaca(免费数字绘图软件)
前端·javascript·后端
非凡ghost42 分钟前
Sucrose Wallpaper Engine(动态壁纸管理工具)
前端·javascript·后端
间彧1 小时前
从零到一搭建Spring Cloud Alibbaba项目
后端
楼田莉子1 小时前
C++学习:C++11关于类型的处理
开发语言·c++·后端·学习