我在 Rust 的第一周学到的东西
Source: Dev.to
如何学习 Rust
一些常被推荐的 Rust 学习资源有:
- The Rust Programming Language – 官方 Rust 书,全面覆盖语言特性。
- Rustlings – 一系列练习,通过修复小代码片段帮助你学习 Rust。
- Rust by Example – 交互式、可运行的代码示例并配有解释。
我个人觉得 Rust by Example 最有帮助,因为它非常契合我的动手学习方式。它让我想起了我学习 Go 时主要使用的 “Tour of Go”。请选择最适合自己学习风格的资源。
如果你更喜欢视频资源,我也觉得 freeCodeCamp 的 Rust 课程(YouTube) 有用,尽管我只看了其中的一小部分。
我在学习过程中大量使用了 ChatGPT 来深入解释概念、帮助理解编译器错误、重构代码等。关键是 不要让 AI 为你写代码——一定要消化它的所有输出并彻底理解。记住 AI 可能会产生幻觉,所以对它的输出要保持怀疑态度。
Rust 的独特特性
语法
Rust 使用双冒号 :: 作为模块、命名空间等的路径分隔符,这与 Go、Python、JavaScript 中使用的点 . 不同。
所有权
所有权是 Rust 独有的核心概念。每个 值 恰好有一个 所有者,当所有者离开作用域时,该值会被释放。
let s = String::from("hello");
这里 s 拥有 String。所有权转移:
let s2 = s; // s 被移动到 s2
// s 之后不能再使用
将变量传递给函数会把所有权转移给该函数:
fn main() {
let s = String::from("hello");
takes_ownership(s); // 所有权移动到函数中
// println!("{}", s); // ❌ 错误:s 已不再有效
}
fn takes_ownership(value: String) {
println!("Got: {}", value);
} // `value` 在这里离开作用域 → String 被释放
返回值同样会把所有权转回调用者。
如果想避免所有权转移,可以通过传递引用来 借用 值:
let s = String::from("hello");
foo(&s); // 所有权未转移
可变引用允许修改:
let mut s = String::from("hello");
foo(&mut s);
Rust 允许任意数量的不可变引用 或 同时只能有一个可变引用,二者不能共存,从而在编译期防止数据竞争。
错误处理
Rust 通过 Result 类型强制显式错误处理。? 运算符可以简洁地传播错误。
fn foo() -> Result<(), std::io::Error> {
// …
Ok(())
}
fn bar() -> Result<(), std::io::Error> {
let data = foo()?; // 若有错误则传播
// 使用 `data`
Ok(())
}
如果 foo 返回 Ok(value),value 会被赋给 data;否则错误会提前从 bar 返回。这取代了 Go 中更冗长的错误检查模式:
data, err := foo()
if err != nil {
return "", err
}
宏
宏通过在编译时展开为代码实现元编程。调用时使用后缀 !,例如 println!。
使用 macro_rules! 的一个简单宏示例:
macro_rules! add_one {
($x:expr) => {
$x + 1
};
}
fn main() {
let a = add_one!(5);
println!("{}", a); // 打印 6
}
编译器会在编译前把 add_one!(5) 展开为 5 + 1。
Trait(特征)
Trait 类似于 Go 或其他面向对象语言中的接口。它们定义了一组必须实现的方法,供类型实现。
trait Greet {
fn greet(&self) -> String;
}
struct Person {
name: String,
}
impl Greet for Person {
fn greet(&self) -> String {
format!("Hello, my name is {}!", self.name)
}
}
用 Rust 构建一个简单的 HTTP 服务器
为了检验我的 Rust 知识,我挑战自己编写了一个基础的 HTTP 服务器。你可以在 [here] 查看完整代码。