常见集合
-
- 1.使用Vector存储列表
-
- 1.1新建vector
-
- 1.新建一个空的vector来存储i32类型的值
- 2.新建一个包含初值的vector
- 1.2更新vector
- 1.3读取vector的元素
-
- 1.使用索引语法或get方法来访问vector中的项
- 2.在拥有vector中项的引用的同时向其增加一个元素
- 1.4遍历vector中的元素
-
- 1.通过for循环遍历vector的元素
- 2.遍历vector中元素的可变引用
- 1.5使用枚举来存储多种类型
- 1.6丢弃vectorr时也会丢弃其所有元素
- 1.7移除vector的元素
- 2.使用字符串存储UTF-8编码的文本
-
- 2.1什么是字符串
- 2.2新建字符串
-
- 1.新建一个空的String
- 2.使用to_string方法从字符串字面值创建String
- 3.使用String::from函数从字符串字面值创建String
- 2.3更新字符串
-
- 1.使用 push_str 和 push 附加字符串
- 2.4使用 +运算符或 format!宏拼接字符串
-
- 1.使用运算符 + 将两个String值合并到一个新的String值中
- 2.使用 format! 宏
- 2.5索引字符串
- 2.6字符串slice
- 2.7遍历字符串的方法
-
- 3.使用Hash Map存储键值对
-
- 3.1新建一个哈希map
- 3.2访问哈希map中的值
-
- 1.访问哈希map的值
- 2.访问哈希map的键值对
- 3.哈希map和所有权
- 4.更新哈希map
-
- 1.覆盖一个值
- 2.只在键没有对应值时插入键值对
- 3.根据旧值更新一个值
1.使用Vector存储列表
- vector允许我们一个挨着一个地存储一系列数量可变的值
1.1新建vector
1.新建一个空的vector来存储i32类型的值
let v: Vec<i32> = Vec::new();
2.新建一个包含初值的vector
- 为了方便Rust提供了Vec!宏,这个宏会根据提供的值来创建一个新的Vector
let v = vec![1,2,3];
1.2更新vector
let mut v = Vec::new();
v.push(1);
v.push(2);
v.push(3);
1.3读取vector的元素
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中项的引用的同时向其增加一个元素
fn main() {
let mut v = vec![1, 2, 3, 4, 5, 6];
let first = &v[0];
v.push(6);
println!("The first element is: {first}");
}
1.4遍历vector中的元素
1.通过for循环遍历vector的元素
let v = vec![110,23,96];
for i in &v{
println!("{i}")
}
2.遍历vector中元素的可变引用
let mut v = vec![300,23,54];
for i in &mut v{
*i += 50;
}
1.5使用枚举来存储多种类型
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在其离开作用域时会被释放
{
let v = vec![1,2,3,4];
}
1.7移除vector的元素
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} ");
}
}
2.使用字符串存储UTF-8编码的文本
2.1什么是字符串
- Rust的核心语言中只有一种字符串类型: 字符串 slice str,通常以被借用的形式出现 &str
- 字符串(String)类型由Rust标准库提供,而不是编入核心语言,它是一种可增长、可变、可拥有、UTF-8编码的字符串类型
- Rustaceans提及Rust中的"字符串"时,可能指的是String 或 string slice &str类型,而不是其中仅仅一种类型
2.2新建字符串
1.新建一个空的String
let mut s = String::new();
2.使用to_string方法从字符串字面值创建String
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最终做了完全相同的工作
let s = String::from("initial contents");
2.3更新字符串
- String的大小可以增加,其内容也可以改变
- 可以使用 + 运算符或 format! 宏来拼接String值
1.使用 push_str 和 push 附加字符串
- 可以通过 push_str 方法来附加字符串slice,从而使 String 变长
fn main() {
let mut str = String::from("foo");
let new_str = "bar";
str.push_str(new_str);
println!("new_str is {new_str}");
}
fn main() {
let mut s = String::from("lo");
s.push('l');
println!("{s}");
}
2.4使用 +运算符或 format!宏拼接字符串
1.使用运算符 + 将两个String值合并到一个新的String值中
fn main() {
let s1 = String::from("Hello, ");
let s2 = String::from("world");
let s3 = s1 + &s2;
println!("{s3}");
}
2.使用 format! 宏
let s1 = String::from("tic");
let s2 = String::from("tac");
let s3 = String::from("toe");
let s = s1 + "-"+ &s2 + "-" + &s3;
let new_s = format!("{s1}-{s2}-{s3}");
2.5索引字符串
- Rust的字符串不支持索引
- String是一个Vec< u8>的封装
2.6字符串slice
let hello = "Здравствуйте";
let s = &hello[0..4];
2.7遍历字符串的方法
1.字符
for c in "Зд".chars(){
println!("{c}");
}
2.字节
for b in "Зд".bytes(){
println!("{b}");
}
3.使用Hash Map存储键值对
- 允许我们将值与一个特定的键(key)相关联
- 所有的键必须是相同类型,值必须都是相同类型
3.1新建一个哈希map
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的值
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的键值对
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}");
for (key, value) in &scores {
println!("{key}: {value}");
}
}
3.哈希map和所有权
- i32实现了Copy trait的类型,其值可以拷贝进哈希map
- String这种拥有所有权的值,其值将被移动到哈希map会称为这些值的所有者
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);
}
4.更新哈希map
1.覆盖一个值
use std::collections::HashMap;
let mut scores = HashMap::new();
scores.insert(String::from("Blue"),10);
scores.insert(String::from("Blue"),25);
println!("{:?}",scores);
2.只在键没有对应值时插入键值对
- Entry 的 or_insert 方法在键对应的值存在时就返回这个值的可变引用,如果不存在则将参数作为新值插入并返回新值的可变引用
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);
}
3.根据旧值更新一个值
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);
}