Rust
install
rustup
rustc
cargo
cargo cmd
cargo run
cargo build --release
cargo install
安装二进制命令cargo add ..
安装依赖cargo test
运行时#[cfg(test)]
属性,条件编译生效
language
-
conditional
continue/break
支持标签'tag
跳出loop
唯一返回有意义值的循环结构,保证至少被输入一次for
语句支持对数组进行迭代(但不支持元组)rust
中没有传统的for (i = 0; i < 3; i++)
- 更倾向于使用迭代器
(iterator)
和for
循环结构来进行循环操作
-
type
array [T;N]
tuple (T,) t.0
<T=b>
表示在泛型类型参数T没有明确指定类型的情况下,将使用类型b
作为默认类型
-
match
-
match 支持 guard,
#[test] fn test_match_usage() { let input = 'x'; match input { 'q' => println!("Quitting..."), 'a' | 's' | 'w' | 'd' => println!("Movining..."), '0'..='9' => println!("number input"), key if key.is_lowercase() => println!("Lowercase: {key}"), _ => println!("other..."), } }
-
-
let
控制流-
if let
表达式 -
while let
-
let else expressions
- "else" 分支必须执行不同的结束方式, 如
return、break 或 panic
- "else" 分支必须执行不同的结束方式, 如
-
let else
fn hex_or_die_trying(maybe_string: Option<String>) -> Result<u32, String> {
let Some(s) = maybe_string else {
return Err(String::from("got None"));
};let Some(first_byte_char) = s.chars().next() else { return Err(String::from("got empty string")); }; let Some(digit) = first_byte_char.to_digit(16) else { return Err(String::from("not a hex digit")); }; return Ok(digit);
}
-
-
references
let mut x_coord: &i32
vslet x_coord: &mut i32
- 前者是共享引用,可以改变 目标值 x_coord
- 后者是独占引用,可以改变持有的引用值内容,但不可改变目标值 x_coord
rust 中只有可变变量才能创建可变引用
fn main() { let mut x = 5; let y = &mut x; // 创建对可变变量 x 的可变引用 y *y += 1; // 通过可变引用修改变量 x 的值 println!("x: {}", x); // 输出修改后的 x 的值 }
-
Macros
assert_ne assert_eq assert
-
Error
e @ Err(_)
vsErr(e)
- 前者 e 值 绑定 Err(_), 后者绑定 _
-
std lib
core
嵌入式常用,大部分不依赖 libc 或 操作系统上的分配器alloc
全局堆分配器 Vec,Box,Arcstd
Trait
-
比较
PartialEq and Eq
(eq 自反性)PartialOrd and Ord
partial_cmp
-
运算符
std::ops
Add...
-
From
和Into
类型转换- 实现
From
后,系统会自动实现Into
- 实现
-
as
显式强制类型转换 -
Read
和Write
对 u8 来源进行抽象化处理 -
Default
为类型生成默认值- 可以通过 #[derive(Default)] 派生出它
- 若为结构体,则其中所有类型也都必须实现
Default
-
闭包
Fn FnMut FnOnce
- 默认情况下,闭包会依据引用来捕获数据(如果可以的话)
- move 关键字则可让闭包依据值 来捕获数据
-
支持trait 嵌套组合
-
示例
trait TraitA { fn method_a(&self); } trait TraitB { fn method_b(&self); } trait CombinedTrait: TraitA + TraitB { fn combined_method(&self) { self.method_a(); self.method_b(); } }
-
-
动态分发
Box<dyn Pet>
Mem
-
程序分配内存
- 栈:局部变量的连续内存区域。
- 值在编译时具有已知的固定大小。
- 速度极快:只需移动一个栈指针。
- 易于管理:遵循函数调用规则。
- 优秀的内存局部性。
- 堆:函数调用之外的值的存储。
- 值具有动态大小,具体大小需在运行时确定。
- 比栈稍慢:需要向系统申请空间。
- 不保证内存局部性。
- 栈:局部变量的连续内存区域。
-
内存管理方法
- 通过手动内存管理实现完全控制:
c, c++,pascal...
- 运行时通过自动内存管理实现完全安全:
java,python,go..
Rust
通过编译时强制执行正确内存, 基于明确的所有权实现
- 通过手动内存管理实现完全控制:
-
移动语义
- 默认移动语义,但实现
Copy trait
类型则会默认复制 - 在Rust中,克隆是显式的
- 通常的做法是,先使用克隆操作解决借用检查器问题,在后续通过优化消除这些克隆操作
- 默认移动语义,但实现
-
Copy VS Clone
- 复制是指内存区域的按位复制,不适用于任意对象。
- 复制不允许自定义逻辑(不同于 C++ 中的复制构造函数)。
- 克隆是一种更通用的操作,也允许通过实现 Clone trait 来自定义行为。
- 复制不适用于实现 Drop trait 的类型。
-
std::mem::drop
- 只是一个采用任何值的空函数。
- 重要的是它获得了值的所有权,因此在其作用域结束时便会被丢弃
-
references
借用检查shared references
一个或多个共享引用,只读exclusive reference
独占引用,可读写
-
内部可变性
Interior Mutability
持有共享引用又可以改变数据
Cell
非运行时借用检查, 使用&self
移动语义 通过get/set
支持内部可变RefCell
强制运行时借用检查borrow/borrow_mut
Rc
多引用计数允许只读访问,不支持内部可变性
-
slice
- 切片提供对集合
collections
的视图view
- 切片从被切片的类型中借用borrow
- 等价
- &a[0...a.len()] 与 &a[...a.len()]
- &a[2...a.len()] &a[2...]
- &a[...]
- 切片提供对集合
-
lifetimes
- 函数
- 每个没有生命周期注解的参数都会添加一个生命周期注解
- 如果只有一个参数生命周期,则将其赋予所有未加注解的返回值
- 如果有多个参数生命周期,但第一个是self的,则将该 生命周期赋予所有未加注解的返回值
- 结构体
- 如果数据类型存储了借用的数据,则必须对其添加生命周期注解
- 函数
-
迭代器 (next方法决定迭代视图)
Iterator
迭代器操作- 元素操作
next map filter...
- 迭代器方法
for
循环,collect
方法...
- 元素操作
IntoIterator
into_iterIntoIterator::into_iter
获取self
所有权
FromIterator
collectFromIterator
可通过Iterator
构建一个集合implementations of FromIterator for Vec, HashMap, etc
Mod
-
crate
根目录src/lib.rs
(对于库 crate, 入口文件)src/main.rs
(对于二进制文件 crate)
-
层次结构
-
若省略模块内容,则会指示 Rust 在另一个文件中查找:
mod garden;
-
module/mod.rs
rust2018 之前 -
引入
filename.rs
来替代filename/mod.rs
-
即使主模块是文件,更深层次嵌套也可以使用文件夹
src/ ├── main.rs ├── top_module.rs └── top_module/ └── sub_module.rs
-
Rust
寻找模块的位置可通过编译器指令更改#[path = "some/path.rs"] mod some_module;
-
-
可见性
- 默认情况下,模块项是私有的
- 父项和同级子项始终可见
pub(crate)
关键字来指定一个项(函数、结构体、枚举等)在当前crate
中可见,但在其他crate
中不可见。
-
路径
pub use
重新导出foo
或self::foo
是指当前模块中的foo
crate::foo
是指当前crate
的根中的foo
绝对路径bar::foo
是指bar
crate 中的foo
,绝对路径
Test
-
在
Rust
中,空的代码块 {} 是一个表达式,它的值是 (),表示一个空的元组 -
test/
目录支持集成测试 -
lint / Clippy
静态代码分析工具fn main() { println!("length: {}", collatz_length(11)); } fn collatz_length(mut n: i32) -> u32 { let mut len= 1; while n > 1 { n = if n % 2 == 0 { n / 2 } else { 3 * n + 1 }; len += 1; } len } #[test] fn test_collatz_length() { assert_eq!(collatz_length(11),15); }