通用集合类型
土豆 2023/3/11
动态数组(vector)可以让你连续地存储任意多个值。
字符串(string)是字符的集合。
哈希映射(hash map)可以让你将值关联到⼀个特定的键上,它是另外⼀种数据结构—映射 (map)的特殊实现。
# 动态数组
// #[derive(Debug)]
fn main() {
// 1.创建动态数组
// 创建⼀个⽤来存储i32数据的空动态数组
let v1: Vec<i32> = Vec::new();
// 使⽤初始值去创建动态数组
let v2 = vec![1, 2, 3];
// 2.更新动态数组
let mut v3 = Vec::new();
v3.push(5);
v3.push(6);
v3.push(7);
// 3.读取动态数组中的元素
let v4 = vec![1, 2, 3, 4, 5, 6];
// 索引方式读取
let third: &i32 = &v4[2];
println!("the third element is {}", third);
// get方法读取 v4.get(2)类型Option<&i32>
match v4.get(2) {
Some(third_2) => println!("the third element is {}", third_2),
None => println!("There is no third element."),
}
// 4.遍历动态数组中的值
let v5 = vec![100, 32, 57];
for i in &v5 {
// i 数组中的值
println!("{}", i)
}
// 5.使用枚举来存储多个类型的值
enum SpreadsheetCell {
Int(i32),
Float(f64),
Text(String),
}
let row = vec![
SpreadsheetCell::Int(3),
SpreadsheetCell::Text(String::from("blue")),
SpreadsheetCell::Float(10.12),
];
}
# 字符串
// #[derive(Debug)]
fn main() {
// 1.创建字符串
// 创建空字符串
let mut s1 = String::new();
// to_string⽅法基于字符串字⾯量创建String
let data = "initial contents";
let s2 = data.to_string();
// 使⽤String::from函数基于字符串字⾯量创建String
let s3 = String::from("hello world");
// 2.更新字符串
let mut s4 = String::from("foo");
s4.push_str("bar"); // foobar
// 将⼀个字符添加到String中 char 类型
s4.push('1'); // foobar1
// 拼接字符串
let s5 = String::from("Hello,");
let s6 = String::from("world");
let s7 = s5 + &s6; // 注意这⾥的s5已经被移动且再也不能被使⽤了
// 使用format!宏拼接
let s8 = String::from("tic");
let s9 = String::from("tac");
let s10 = String::from("toe");
let s11 = format!("{}{}{}", s8, s9, s10); // tictactoe
// 3.遍历字符串的⽅法
// 打印chat
for c in "abcd".chars() {
println!("{}", c)
}
// 打印byte
for c in "abcd".bytes() {
println!("{}", c)
}
}
# 哈希映射
// #[derive(Debug)]
use std::collections::HashMap;
fn main() {
// 1.创建一个哈希映射
let mut scores = HashMap::new();
scores.insert(String::from("Blue"), 10);
scores.insert(String::from("Yellow"), 50);
// 动态数组转换为哈希映射
let teams = vec![String::from("Blue"), String::from("Yellow")];
let initial_scores = vec![10, 50];
// 类型标记HashMap<_, _>不能被省略,
// 因为collect可以作⽤于许多不同的数据结构,如果不指明类型的话,
// Rust就⽆法知道我们具体想要的类型。但是对于键值的类型参数,我们则使⽤了下画线占位
let scores2: HashMap<_, _> = teams.iter().zip(initial_scores.iter()).collect();
// 2.访问哈希映射中的值
let team_name = String::from("Blue");
let score = scores.get(&team_name);
// 遍历
for (key, value) in &scores {
println!("{}:{}", key, value)
}
// 3.更新哈希映射
// 覆盖旧值
scores.insert(String::from("Blue"), 10);
scores.insert(String::from("Blue"), 20);
// 如果该分数值不存在,就将50作为初始值插⼊
scores.insert(String::from("Blue"), 10);
scores.entry(String::from("Yellow2")).or_insert(50);
scores.entry(String::from("Blue")).or_insert(50);
// 输出 {Yellow2:50,Blue:10}
// 基于旧值来更新值
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);
// 代码中的⽅法or_insert实际上为我们传⼊的键返回了⼀个指向关联值的可
// 变引⽤(&mut V)。这个可变引⽤进⽽被存储到变量count上,为了对
// 这个值进⾏赋值操作,我们必须⾸先使⽤星号(*)来对count进⾏解
// 引⽤。由于这个可变引⽤会在for循环的结尾处离开作⽤域,所以我们
// 在代码中的所有修改都是安全且满⾜借⽤规则的。
*count += 1;
}
println!("{:?}", map); // {"world": 2, "hello": 1, "wonderful": 1}
}