Rust 笔记

参考

《Rust Primer》

《Rust 编程之道》

《Rust Course》(Rust 语言圣经)

THU《程序设计训练(Rust)》课件

  • 裸指针(不安全): *const T*mut T
  • 单字节字符 b'H' ,单字节字符串 b'Hello' ,仅限 ASCII 字符; r#"..."# 表示不转义字符串;
  • String&str 很廉价,而反之涉及分配内存,代价相对更高;
  • 即使结构体是公有的,成员仍然默认私有;枚举如果是公有的则其成员均为公有;
  • 可以在 match 中通过 refref mut 获取对应变量的引用;
  • try! 宏在 Ok 时提取内部值,否则直接 return 期望返回的 Error 类型;现在可以直接使用 ?
  • 使用 io::stdin.read_line(&mut String) 读入;
  • Rust 项目结构:
1
2
3
4
5
6
7
8
9
Project/
|-- cargo.toml
|-- cargo.lock
|-- src/
|-- |-- main.rs
|-- |-- lib.rs
|-- |-- bin/
|-- tests/
|-- examples/
  • for (i, j) in (5..10).enumerate() 使 i 为循环次数下标;
  • 使用 #derive[(...)] 为类型自动添加一些 trait,常用: CloneCopyDebugDefaultEqPartiaEqOrdPartialOrdHash
  • Eq trait 表示任意两个值要么 == 要么 != ,它不包含方法,仅用作标记; PartialEq 提供部分等价关系,包含一个 eq 方法;实现了 Eq 的必然实现了 PartialEq<>>=<= 实现的是 PartialOrdPartialEq 满足对称性与传递性, Eq 还满足自反性;
  • 所有硬编码字符串均为 &'static str
  • +-*/% 分别实现在 std::ops::Add/Sub/Mul/Div/Rem&|^<<>> 分别实现在 std::ops::BitAnd/BitOr/BitXor/Shl/Shr
  • 函数参数支持模式匹配: fn print_age((_, age): (&str, i32));
  • 发散函数(Diverging function)不返回值,返回值处使用 !
  • trait 可以继承: trait Son : Parent ,之后实现 Son 的类型也要实现 Parent
  • Copy trait 继承 Clone trait: pub trait Copy: Clone;
  • Rust 为 VecHashMap 实现了 IntoIterator trait,从而支持直接 for a in vec 循环;无限迭代器: let inf_seq = (1..).into_iter();VecHashMap 实现了 FromIterator trait,以支持 (1..10).collect() 等操作;
  • foldreduce 的区别:后者带初始值;取前 n 个: let v_take = v.iter().cloned().take(2).collect::<Vec<_>>();skip(n) 跳过前 n 个;
  • Prelude 的一部分:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
std::marker::{Copy, Send, Sized, Sync}
std::ops::{Drop, Fn, FnMut, FnOnce}
std::mem::drop
std::boxed::Box
std::borrow::ToOwned
std::clone::Clone
std::cmp::{PartialEq, PartialOrd, Eq, Ord}
std::convert::{AsRef, AsMut, Into, From}
std::default::Default
std::iter::{Iterator, Extend, IntoIterator, DoubleEndedIterator, ExactSizeIterator}
std::option::Option::{self, Some, None}
std::result::Result::{self, Ok, Err}
std::slice::SliceConcatExt
std::string::{String, ToString}
std::vec::Vec
  • Into/From trait 分别实现了 U::from(T)U::into(T) ,会消耗所有权;实现了 From 会自动实现 IntoTryFromTryInto 返回 Result ;同样还有 ToStringFromStr
  • AsRef<U> 实现了将 T 类型对象 a 通过 a.as_ref() 得到 &U ,不消耗所有权; AsMut 同理;
  • 实现了 Deref<Target=U> 的类型 T 可以通过 &T 传参给 &U ;调用函数时,Rust 会提供任意多层自动解引用;
  • 不可以使用 i32/i64 作为下标,需要 as usize
  • 不同于 C++,Rust 的块注释 /* */ 可以嵌套;
  • 变量有引用存在时,不能移交其绑定数据的所有权;
  • 结构体有域级的访问控制,但没有域级的可变性控制,因此可以对内部变量标记 pub 而不能标记 mut ;结构体的域访问控制是针对模块而非结构体本身的,即其私有成员可以被同模块的其它函数访问;
  • 使用 s.chars().nth(i) 访问 String
  • 常用 Option<T> 相关函数:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
fn unwrap<T>(self) -> T {
match self {
None => panic!("Called `Option::unwrap()` on a `None` value"),
Some(value) => value,
}
}

fn map<U, F>(self, f: F) -> Option<U>
where F: FnOnce(T) -> U {
match self {
None => None,
Some(x) => Some(f(x))
}
}

fn and_then<U, F>(self, f: F) -> Option<U>
where F: FnOnce(T) -> Option<U> {
match self {
Some(x) => f(x),
None => None,
}
}

impl<T> Option<T> {
fn unwrap_or<T>(self, default: T) -> T {
match self {
None => default,
Some(value) => value,
}
}
}

impl<T> Option<T> {
fn unwrap_or_else<T>(self, f: F) -> T
where F: FnOnce() -> T {
match self {
None => f(),
Some(value) => value,
}
}
}

fn is_some(&self) -> bool
fn is_none(&self) -> bool
fn map_or<U, F>(self, default: U, f: F) -> U // U 类型的默认值
where F: FnOnce(T) -> U
fn map_or_else<U, D, F>(self, default: D, f: F) -> U // D 类型的闭包用于计算默认值
where D: FnOnce() -> U, F: FnOnce(T) -> U
fn ok_or(self, err: E) -> Result<T, E>
fn ok_or_else(self, default: F) -> Result<T, E> // 与 unwrap_or 相似,用于错误处理。
where F: FnOnce() -> E
fn and<U>(self, optb: Option<U>) -> Option<U> // 如果 self 是 None,则返回 None,否则返回 optb。
fn or(self, optb: Option<T>) -> Option<T> // 如果 self 是 Some(_),则返回 self,否则返回 optb。
fn xor(self, optb: Option<T>) -> Option<T> // 如果 self 和 optb 恰好有一个是 Some(_),则返回这个 Some,否则返回 None。
  • Rust 提供的容器: Vec<T>VecDeque<T>LinkedList<T>HashMap<K, V>BTreeMap<K, V>HashSet<T>BTreeSet<T>BinaryHeap<T>
  • Rust 的线程发生恐慌,和创建此线程的线程无关,其它线程能读取恐慌线程的信息;
  • 所有不带内部可变性的类型和只包含 Sync 类型的复合类型会自动获得 Sync;
  • 为一个结构体实现 Hash trait,会将 nameage 传播给一个实现了 Hasher 的对象的可变引用(state)中,state 将它们组合后算出对应哈希值:
1
2
3
4
5
6
impl Hash for Person {
fn hash<H: Hasher>(&self, state: &mut H) {
self.name.hash(state);
self.age.hash(state);
}
}
  • 有时需要用大括号制造一个新域来使用某变量可变引用,从而不妨碍之后再获得某变量的其它引用;
  • for line in &textsfor line in texts.iter() 的语法糖;
  • Trait 对象隐式具有 'static 生命周期,但当闭包捕获的变量具有更短生命周期时,闭包生命周期也随之缩小;
  • 编译器只考虑被调用函数的签名而不会深入函数体,因此改变函数实现而不改变签名不会影响编译结果;
  • 迭代器的 clone() 仅拷贝一个栈上的引用,因此非常高效;
  • 枚举成员占用的内存空间大小跟最大的成员对齐;
  • borrow 得到的是 Ref 类型,其生命周期与调用者(可能是引用)的生命周期相同;它通过 Deref 实现和 &T 相同效果的自动解引用;
1
2
fn borrow<'a>(&'a self) -> Ref<'a, T>
fn borrow_mut<'a>(&'a self) -> RefMut<'a, T>