【跟小嘉学 Rust 编程】一、Rust 编程基础
【跟小嘉学 Rust 编程】二、Rust 包管理工具使用
【跟小嘉学 Rust 编程】三、Rust 的基本程序概念
【跟小嘉学 Rust 编程】四、理解 Rust 的所有权概念
【跟小嘉学 Rust 编程】五、使用结构体关联结构化数据
【跟小嘉学 Rust 编程】六、枚举和模式匹配
【跟小嘉学 Rust 编程】七、使用包(Packages)、单元包(Crates)和模块(Module)来管理项目
【跟小嘉学 Rust 编程】八、常见的集合
Rust 的标准库包括许多非常有用的数据结构,称为集合。大多数其他数据类型表示一个特定的值,但是集合可以包含多个值。与内置数组和元组类型不同,这些集合指向的数据存储在堆中。
本章节主要讲解 Vector、String、HashMap
主要教材参考 《The Rust Programming Language》
Vector 由标准库提供,可以存储多个相同类型的数据,其值在内存中连续存放。
Vec:: new
创建 Vector 类型变量使用 Vec:: new
可以创建一个空的 Vector
let v: Vec<i32> = Vec::new();
vec!
宏 创建 Vector 类型变量 let v = vec![1, 2, 3];
with_capacity
创建 Vector 类型变量//定义一个容量为6的空向量,这时向量的长度为0
let mut vec: Vec<i32> = Vec::with_capacity(6);
//添加第一个元素,此时长度为1
vec.push(1);
//添加第二个元素,长度加1
vec.push(2);
let mut v = Vec::new();
v.push(5);
v.push(6);
v.push(7);
v.push(8);
insert(index: usize, element: T)
方法fn main() {
let mut v = Vec::new();
v.insert(0, 3);
}
index 从0 开始
pop
方法使用 pop 方法可以弹出最后一个值。
remove
方法按照索引方式删除。
retain
方法只保留符合条件的元素。
let mut vec = vec![1, 2, 3, 4];
vec.retain(|&x| x % 2 == 0);
clear
方法删除所有的值。
let v = vec![1, 2, 3, 4, 5];
let third: &i32 = &v[2];
println!("The third element is {third}");
使用 索引方式 获取值操过索引范围程序则会抛出 panic。
let v = vec![1, 2, 3, 4, 5];
let third: Option<&i32> = v.get(2);
match third {
Some(third) => println!("The third element is {third}"),
None => println!("There is no third element."),
}
let v = vec![100, 32, 57];
for i in &v {
println!("{i}");
}
let mut v = vec![100, 32, 57];
for i in &mut v {
*i += 50;
}
let mut v = vec![1, 2, 3];
v.clear();
assert!(v.is_empty());
let vector : Vec<i32> = vec![2,11,10];
vector.contains(&200); // false
vector.contains(&2); // true
let mut vector = vec![10,22,3,14,51,16,27];
vector.sort(); // 排序
vector.binary_search(&22); // 二分查找
使用枚举可以让 Vector 存放不同类型的数据。
enum SpreadsheetCell {
Int(i32),
Float(f64),
Text(String),
}
let row = vec![
SpreadsheetCell::Int(3),
SpreadsheetCell::Text(String::from("blue")),
SpreadsheetCell::Float(10.12),
];
fn main() {
let str1:String = "hello".to_string();
let str2:String = String::from("hello");
let str2:String = "hello".to_owned();
}
let mut str1:String = "hello".to_string();
let str2:String = String::from("hello");
let str2:String = "hello".to_owned();
str1.insert(1, 'c');
str1.insert_str(1, "str");
for c in "Зд".chars() {
println!("{c}");
}
for b in "Зд".bytes() {
println!("{b}");
}
HashMap
HashMap
类型HashMap
使用散列函数存储 K类型键到 V类型值的映射,该函数决定如何将这些键和值放入内存。
use std::collections::HashMap;
let mut scores:HashMap<String, i32> = HashMap::new();
如果创建空对象,不插入内容,编译器无法进行类型自动推导,所以需要显示指定类型。
use std::{vec, collections::HashMap};
fn main() {
let teams = vec![String::from("Blue"), String::from("Yellow")];
let intial_score = vec![10,50];
let scores:HashMap<_,_> = teams.iter().zip(intial_score.iter()).collect();
println!("{:?}", scores);
}
with_capacity
方法来创建 HashMaplet mut scores:HashMap<String, i32> = HashMap::with_capacity(16);
use std::collections::HashMap;
fn main() {
let mut scores:HashMap<String, i32> = HashMap::with_capacity(16);
let key= String::from("value");
let value = 32;
scores.insert(key, value);
}
需要注意 HashMap和所有权的问题
get 方法返回的是 Option 枚举。
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!("{} not exits", team_name),
}
}
这其实是 Optional 的使用方法
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);
}
use std::collections::HashMap;
fn main() {
let mut scores = HashMap::new();
scores.insert(String::from("Blue"), 10);
scores.insert(String::from("Yellow"), 50);
for (key, value) in &scores {
println!("{key}: {value}");
}
}
use std::collections::HashMap;
fn main() {
let mut scores = HashMap::new();
scores.insert(String::from("Blue"), 10);
scores.insert(String::from("Blue"), 25);
println!("{:?}", scores);
}
use std::collections::HashMap;
fn main() {
let mut scores = HashMap::new();
scores.insert(String::from("Blue"), 10);
scores.entry(String::from("Yellow")).or_insert(50);
scores.entry(String::from("Blue")).or_insert(50);
println!("{:?}", scores);
}
use std::collections::HashMap;
fn main() {
let text = "hello world wonderful world";
let mut map = HashMap::new();
for word in text.split_whitespace() {
let count = map.entry(word).or_insert(0);
*count += 1;
}
println!("{:?}", map);
}
默认情况下,HashMap 使用加密功能强大的 Hash 函数(SipHash),可以抵抗拒绝服务(DoS)攻击。该方法不是可用的最快的 Hash 算法,但是具有更好的安全性。
可以指定不同的 hasher(实现 BuildHasher trait) 来切换到另个函数。
以上就是今天要讲的内容