渗入生命的铁锈味——rust学习笔记

铁锈味是血液的味道,虽然我不知道rust的命名是否与此相关,但我觉得这样想似乎也无伤大雅。毕竟学起来真的有点想吐血()
初学rust,它带给我最大的感受是编译器近乎苛刻的严格。诚然,这样的严格能从一开始就避免一些问题,但未免有些束缚住程序员的思维。不过就我而言,在对内存管理完全没有信心的情况下,选择rust的确是个正确的选择。
就像现实中的很多情况一样,rust的很多要求既是禁锢也是保护。这让我想起中学时的命题作文,就像当时对其的比喻一样,这也是“带着镣铐跳舞”。
保证内存安全
默认不可变性
为了保证内存安全,rust中变量默认是不可变的,这意味着一旦变量被赋值,它的值就不能被修改。如果需要修改变量的值,必须显式地使用 mut
关键字声明其为可变的。
1 | let x = 5; // x 是不可变的 |
这样可以很明确地标注出哪些变量是将要被改变的,对编程过程也有一定帮助(虽然好像和其他语言用const关键字标记不变起到的作用差不多)
所有权系统
单所有者原则
每个资源在任何时候都有一个且只有一个所有者。当所有者超出作用域时,资源会被自动释放。这个原则通过变量的绑定和解绑定来实现。
1 | { |
移动语义
当一个资源的所有权从一个变量移交给另一个变量时,原来的变量将不再有效,以防止资源的双重释放(double free)问题。这称为移动语义。(突然想起写C++时总是二次析构的痛苦回忆)
1 | let s1 = String::from("hello"); |
拷贝语义
对于简单的标量类型(如整数、浮点数、布尔值和字符)以及实现了 Copy
特征的类型,Rust 会使用拷贝语义,而不是移动语义。这意味着这些类型的值在赋值时会被拷贝,而不是移动。
1 | let x = 5; |
借用和生命周期
借用(Borrowing)
你可以在不转移所有权的情况下临时借用资源。借用通过引用(&
)实现,分为不可变引用(&T
)和可变引用(&mut T
)。
1 | let s = String::from("hello"); |
引用规则
Rust 的引用规则确保了引用的安全性:
- 在同一作用域内,对于同一个资源,可以有多个不可变引用,但不能有可变引用。
- 在同一作用域内,对于同一个资源,可以有一个可变引用,但不能有其他任何引用。
1 | let mut s = String::from("hello"); |
生命周期注解
生命周期注解用于显式地指明引用的生存期,确保引用在其所有者生存期内有效。编译器会自动推断大多数生命周期,但在某些复杂情况下需要手动注解。
1 | fn first_word(s: &str) -> &str { |
在上面的例子中,first_word
函数接收一个字符串切片的引用,并返回一个字符串切片的引用。编译器会确保返回的引用不会超出 s
的生存期。
生命周期检查
Rust 的借用检查器在编译时会检查引用的生命周期,确保它们在其所有者生存期内有效。这避免了悬挂引用(dangling references)问题。
1 | let s: String; |
智能指针和资源管理
Rust 使用智能指针(如 Box
、Rc
和 Arc
)来管理资源,并通过它们的所有权和借用规则确保内存安全。
1 | let x = Box::new(5); // x 是一个堆分配的整数 |
Rust与CTF
纵使rust有那么多保证内存安全的措施,但为了一些功能的实现,很多时候也很难保证不使用unsafe
,这个时候就会出现可能的内存问题(所以unsafe是为了出问题可以追责?[思考])
- 标题: 渗入生命的铁锈味——rust学习笔记
- 作者: Wang1r
- 创建于 : 2025-01-26 16:24:00
- 更新于 : 2025-04-07 12:35:18
- 链接: https://wang1rrr.github.io/2025/01/26/渗入生命的铁锈味——rust学习笔记/
- 版权声明: 本文章采用 CC BY-NC-SA 4.0 进行许可。