概述
汇合都是存储在 heap 中
1. Vector
- 类型为 Vec<T>
- 由规范库 std 提供
- 可存储多个数据类型雷同的值
- 值在内存中间断寄存
创立 Vector
- 应用 Vec::new 可创立一个空的 vector
-
应用 vec!创立带初值的 vector
fn main() {let vec: Vec<i32> = Vec::new(); let vec1 = vec![1, 2, 3]; }
更新 Vector
-
push 增加成员
fn main() {let mut vec: Vec<i32> = Vec::new(); vec.push(1); }
-
pop 移除最初一个成员并返回
#[derive(Debug)] enum Type {Int(u32), Float(f64), Text(String) } fn main() { let mut vec = vec![Type::Int(12), Type::Float(12.2), Type::Text(String::from("haha")) ]; println!("{:?}", vec.pop()); //Some(Text("haha")) println!("{:?}", vec); // [Int(12), Float(12.2)] }
拜访 Vector
-
下标索引
- 比拟灵便,但拜访越界时会导致程序 panic
-
get 办法
- 返回一个 options 枚举,能进行越界的异样解决,绝对繁琐但更平安
fn main() {let vec = vec![1, 2, 3]; let two = vec[1]; let getTwo = match vec.get(1) {Some(value) => {println!("value is {}", value); Some(value) }, None => {println!("None"); None } }; println!("{}", two); // 2 println!("{:?}", getTwo); // Some(2) }
遍历 Vector
fn main() {let mut vec = vec![1, 2, 3];
vec.push(4);
for item in &mut vec {println!("{}", item);
*item += 50;
}
println!("{:?}", vec) //[51, 52, 53, 54]
}
利用 enum 枚举来实现寄存不同的数据类型
enum Type {Int(u32),
Float(f64),
Text(String)
}
fn main() {
let vec = vec![Type::Int(12),
Type::Float(12.2),
Type::Text(String::from("haha"))
];
}
2. String
- Rust 中字符串是 byte 的汇合,其提供了一些办法,能将 byte 解析为文本
-
Rust 的 外围语言层面 只提供了一种字符串类型:字符串切片 &str
- 字符串切片是对存储在其余中央 UTF-8 编码的字符串的 援用 ,比方存储在二进制文件中的 字符串字面值
-
String 类型
- 是规范库所提供的,而不是语言层面提供
- 可增长,可批改,可取得所有权
- Rust 中的字符串只的是 String 和 &str 这两种,规范库中还提供了其余的字符串类型:OsString,OsStr,CString,CStr
创立 String
fn main () {
// 创立空字符串
let str1 = String::new();
// 将字符串切片转为 String
let str2 = "hello,string".to_string();
let str3 = String::from("haha");
}
更新 String
- push_str
- push
- +
-
format!
fn main () {let str1 = String::new(); let str2 = "hello,string".to_string(); let str3 = String::from("haha"); // 更新 String let mut str4 = String::from("base,"); // 1. 拼接字符串切片 str4.push_str(&str3); println!("{}", str4); // base, haha // 2. 拼接单个字符 str4.push('!'); println!("{}", str4); // base, haha! // 3. 应用 + 拼接,这种形式会使得 str4 的所有权产生挪动,后续就不能应用了 let str5 = str4 + &str2; println!("{}", str5); // base, haha!hello,string // 4.format! 进行拼接,这个宏不会取得参数的所有权 let one = String::from("one"); let two = String::from("two"); let three = String::from("three"); let merge_str = format!("{}-{}-{}", one, two, three); println!("{}", merge_str); // one-two-three }
拜访 String
-
不反对应用 索引 的模式拜访
- 因为 一个字符可能不止占用一个字节,依照字节进行索引很可能无奈获取到咱们冀望的值,所以 Rust 间接禁止了这种形式
- String 是对 Vec<u8> 的包装
- len 办法获取 String 的字节数,留神不是字符数
-
字符串的单位有以下三个概念
- 字节
- 标量值
- 字形簇 – 规范库没有提供获取这种模式的办法
fn main () {let target = String::from("target"); // 返回 字节 的迭代器 for item in target.bytes() { /* byte item of target: 116 byte item of target: 97 byte item of target: 114 byte item of target: 103 byte item of target: 101 byte item of target: 116 */ println!("byte item of target: {}", item) } // 返回 标量值 的迭代器 for item in target.chars() { /* char item of target: t char item of target: a char item of target: r char item of target: g char item of target: e char item of target: t */ println!("char item of target: {}", item) } }
切割 String
-
能够应用 [] 配合 range 来创立字符串切片
- 但须要审慎应用,如果切割时逾越了字符边界,程序就会 panic,例如指标字符串 target 的第二字符占 2 个字节,这时如果对其第 0, 1 (target[0..2]) 字节位进行切片,则会导致 panic
fn main () {let source_str = String::from("i am source string"); let splice_str = &source_str[0..4]; println!("{}", splice_str); // i am }
3. HashMap<k, v>
- 键值对的模式存储数据
- HashMap 没有在 prelude 中,须要应用 use str::collections::HashMap 引入
创立 HashMap
- HashMap::new
-
collect
use std::collections::HashMap; fn main() {let mut map = HashMap::new(); map.insert("name", 10); println!("{:?}", map); // {"name": 10} // collect 创立 hashmap let keys = vec!["age", "size"]; let values = vec![24, 12]; let new_map: HashMap<_, _> = keys.iter().zip(values.iter()).collect(); println!("{:?}", new_map); // {"age": 24, "size": 12} }
获取 HashMap 成员
- hashMap[key]
-
hashMap.get(key)
use std::collections::HashMap; fn main() {let keys = vec!["age", "size"]; let values = vec![24, 12]; let new_map: HashMap<_, _> = keys.iter().zip(values.iter()).collect(); println!("{:?}", new_map); // {"age": 24, "size": 12} println!("{}", new_map[&"size"]); // 12 match new_map.get(&"age") {Some(v) => println!("{}", v), // 24 None => println!("None") } }
遍历 HashMap
use std::collections::HashMap;
fn main() {let mut config = HashMap::new();
config.insert("a", "A");
config.insert("b", "B");
config.insert("c", "C");
config.insert("d", "D");
for (k, v) in &config {println!("{}, {}", k, v);
}
}
更新 HashMap
-
entry & or_insert
- entry 查看一个 k 是否有值,如果检测到值存在,则返回 value 的可变援用
- or_insert 如果 k 为空则插入一个新值,并返回 value 的可变援用
use std::collections::HashMap; fn main() {let mut config = HashMap::new(); config.insert("a", "A"); config.insert("b", "B"); config.insert("c", "C"); config.insert("d", "D"); // entry 查看一个 k 是否有值,如果检测到值存在,则返回 value 的可变援用 // or_insert 如果 k 为空则插入一个新值,并返回 value 的可变援用 config.entry("a").or_insert("replace_A"); config.entry("e").or_insert("E"); /* { "a": "A", "b": "B", "c": "C", "e": "E", "d": "D", } */ println!("{:#?}", config); // 利用 entry 和 or_insert 的个性实现单词统计 let words = "hello get get set clear good bad bad yep get"; let mut count_map = HashMap::new(); // split_whitespace 依照空格进行拆分,返回一个迭代器 for key in words.split_whitespace() {let value = count_map.entry(key).or_insert(0); *value += 1; } /* { "get": 3, "set": 1, "hello": 1, "bad": 2, "good": 1, "yep": 1, "clear": 1, } */ println!("{:#?}", count_map) }
hash 函数
- HashMap 默认的 hash 算法效率不是最高的,但有不错的安全性
-
能够指定不同的 hasher 来切换 hash 算法
- hasher 是指实现 BuildHasher trait 的类型