1. 数据结构

  Rust的标准库提供了几种数据结构,可用于以各种方式存储和操作数据。如下所示:

  • Vec<T>:一个可增长的数组,可以存储可变数量的T类型元素。它被实现为一个动态分配的数组,并提供对其元素的有效访问。
fn main() {
let mut v = Vec::new();
v.push(1);
v.push(2);
v.push(3);

assert_eq!(v[0], 1);
assert_eq!(v[1], 2);
assert_eq!(v[2], 3);
}
  • LinkedList<T>:一个双链表,可以存储可变数量的类型T的元素。它允许有效地插入和删除列表两端的元素,但与Vec相比,它对单个元素的访问速度较慢。
use std::collections::LinkedList;
fn main() {
let mut list = LinkedList::new();
list.push_back(1);
list.push_back(2);
list.push_back(3);

assert_eq!(list.front().unwrap(), &1);
assert_eq!(list.back().unwrap(), &3);
}
  • HashMap<K, V>:一个哈希表,可以存储从K类型键到V类型值的映射。它提供了基于键值的高效插入、删除和查找。
use std::collections::HashMap;
fn main() {
let mut map = HashMap::new();
map.insert("a", 1);
map.insert("b", 2);
map.insert("c", 3);

assert_eq!(map.get("a"), Some(&1));
assert_eq!(map.get("b"), Some(&2));
assert_eq!(map.get("c"), Some(&3));
}

2. 算法

  Rust标准库还提供了许多算法,可用于对数据执行常用操作。如下所示:

  • sort:使用稳定的排序算法对切片进行就地排序。
fn main() {
let mut v = [5, 2, 1, 3, 4];
v.sort();

assert_eq!(v, [1, 2, 3, 4, 5]);
}
  • binary_search:对排序的切片执行二分查找,以查找给定元素的索引。
fn main() {
let v = [1, 2, 3, 4, 5, 6, 7];

assert_eq!(v.binary_search(&3), Ok(2));
assert_eq!(v.binary_search(&8), Err(7));
}
  • iter::sum:计算迭代器中元素的和。
fn main() {
let v = [1, 2, 3, 4, 5];

let sum: i32 = v.iter().sum();

assert_eq!(sum, 15);
}

  • find:查找迭代器中满足给定闭包的第一个元素,以下2种形式。
fn main() {
let v = [1, 2, 3, 4, 5];
let first_even = v.iter().find(|x| *x % 2 == 0);

assert_eq!(first_even, Some(&2));
}
fn main() {
let v = [1, 2, 3, 4, 5];
let first_even = v.iter().find(|&x| x % 2 == 0);

assert_eq!(first_even, Some(&2));
}
  • minmax:分别查找迭代器中的最小和最大元素。
fn main() {
let v = [1, 2, 3, 4, 5];

let min = v.iter().min();
let max = v.iter().max();

assert_eq!(min, Some(&1));
assert_eq!(max, Some(&5));
}
  • allany:分别确定迭代器中的所有元素或任一元素是否满足给定的闭包。
fn main() {
let v = [1, 2, 3, 4, 5];

let all_even = v.iter().all(|x| x % 2 == 0);
let any_even = v.iter().any(|x| x % 2 == 0);

assert_eq!(all_even, false);
assert_eq!(any_even, true);
}

  • fold:在迭代器上执行fold操作,根据迭代器的元素累积一个值。
// fold函数第一个是初始值,第二个是一个闭包,闭包第一个参数是一个累计值,第二个参数是本次迭代元素的引用,返回值作为下一次迭代的累计值。
fn main() {
let v = [1, 2, 3, 4, 5];

let sum: i32 = v.iter().fold(2, |acc, x| acc + x); //相当于 2 + ((((1 + 2) + 3) + 4) + 5)
let mul: i32 = v.iter().fold(3, |acc, x| acc * x); //相当于 3 * ((((1 * 2) * 3) * 4) * 5)

assert_eq!(sum, 17);
assert_eq!(mul, 360);
}
  • map: 即是对迭代的元素进行一次映射后再返回映射后的结果,collect是将一个迭代器迭代的所有元素组合成一个新的集合
fn main() {
let vec = vec![1, 2, 3, 4, 5];
let vec_str = vec.iter().map(|x| x.to_string()).collect::<Vec<_>>();
assert_eq!(vec_str, ["1", "2", "3", "4", "5"]);
}
fn main() {
let vec = vec![1, 2, 3, 4, 5];
let vec_str: Vec<_> = vec.iter().map(|x| x + 1).collect();
assert_eq!(vec_str, [2, 3, 4, 5, 6]);
}
  • filter 是一个迭代器适配器,它接受一个闭包作为参数,该闭包返回一个布尔值。
fn main() {
let v = [0, 1, 2, 3, 4, 5, 6, 7];
// 错误示例 1
// let list1: Vec<_> = v.iter().filter(|i| i % 3 == 0).collect();
// let list2 = [0, 3, 6];
// assert_eq!(list1, list2);
// 错误示例 2
// let list1: Vec<_> = v.iter().filter(|i| **i % 3 == 0).collect();
// let list2 = [0, 3, 6];
// assert_eq!(list1, list2);
// 错误示例 3
// let list1: Vec<_> = v.iter().filter(|i| **i % 3 == 0).copied().collect();
// let list2 = [0, 3, 6];
// assert_eq!(list1, list2);
// 错误示例 4
// let list1: Vec<_> = v.iter().filter(|i| **i % 3 == 0).copied().collect();
// assert_eq!(list1, [0, 3, 6]);
// 正确示例
let list1: Vec<_> = v.iter().filter(|i| **i % 3 == 0).copied().collect();
let list2 = vec![0, 3, 6];
assert_eq!(list1, list2);
}