语言巡礼 — 三个小程序看懂 Rust 的用法与脾气
语言巡礼 — 三个小程序看懂 Rust 的用法与脾气
这一章讲三件事: Rust 的工具链长什么样;一个带测试、带命令行参数、带错误处理的小程序怎么从零跑起来; 以及怎么用第三方 crate 搭一个 web 服务。原书的立场也在这章亮明:Rust 没有单一「看家特性」, 它的全部设计服务于一个目标——安全的、高性能的系统编程1。 多线程那个程序留给下一章,本章是它的地基。
1. 顶层全景:从安装到三个程序
这一章的骨架是一张「造车流水线」式的流程图:
rustup 装工具链(cargo / rustc / rustdoc)
│ cargo new 建包(两个文件、九行样板)
▼
程序一:命令行 gcd ── 函数、断言、单元测试、命令行参数
│ 顺手带出:trait、迭代器、Result、借用
▼
程序二:Actix web 服务 ── 第三方 crate、async、闭包、derive 宏
│
▼
程序三:多线程曼德博画图(下一章)── 泛型、切片、scoped 线程图说:每一步都建立在前一步的概念上,最后落到并发——那是 Rust 真正的卖点。
本章的主线例子就是程序一:命令行输入 42 56,输出 The greatest common divisor of [42, 56] is 14。
trait、迭代器、Result、借用这四个地基概念,都会在这一个程序上各走一步。
2. 工具链:cargo、rustc、rustdoc
装 Rust 的标准方式是 rustup(类比 Ruby 的 RVM、Node 的 NVM):新版本发布时敲一句 rustup update 就升级2。
装完你得到三个命令,书里给出了具体版本号,cargo 1.85.0、rustc 1.85.0(2025 年 2 月)3:
| 命令 | 干什么 |
|---|---|
cargo | 编译管理 + 包管理 + 通用工具:建项目、构建、运行、管依赖 |
rustc | Rust 编译器本体。平时由 cargo 代为调用 |
rustdoc | 文档工具:把源码里特定形式的注释变成网页 |
cargo new hello 会建好一个包:一个 Cargo.toml(这个文件装的是元数据:包名、版本、edition——示例里是 edition = "2024")
和一个 src/main.rs,内容就是九行的 Hello World4。包(packages)在 Rust 里有个专门名字叫 crate
——不管库还是可执行文件都叫 crate;Cargo 和 crates.io 两个名字都是从这个词来的5。
cargo 的日常循环
建完包,日常就是三个命令转圈:cargo run 一键「编译 + 运行」,输出里能看到它先调 rustc、
再跑产物;cargo test 收集所有 #[test];cargo clean 删掉 target/ 里的全部生成物
(书里的实录:21 个文件、7.7 MB),删完再直接运行编译产物,操作系统报「没有那个文件」——
干净得没有一丝残留6。
编译产物本身在 target/debug/ 下,可以直接执行;放那里是「带调试信息的开发版」。
第 2 章的曼德博程序会用到 cargo build --release——优化版,快得多。
3. 程序一:命令行 gcd
3.1 一个函数里的语法底色
原书用欧几里得算法求最大公约数,一个函数同时演示了半打语法决定:
fn gcd(mut n: u64, mut m: u64) -> u64 {
assert!(n != 0 && m != 0);
while m != 0 {
if m < n {
let t = m; m = n; n = t;
}
m = m % n;
}
n // 没有分号:这个 n 就是返回值
}fn引入函数;参数类型必须写(n: u64是 64 位无符号整数),返回值类型跟在->后面; 但函数体内局部变量的类型不用写,Rust 会推断——let t = m;里t自动是u647。mut(读作 mute,mutable 的缩写):默认变量初始化后不可改;要改就得在声明处明说。 书里说这反而是个阅读提示——带mut的变量接下来会被赋值8。assert!是宏(名字后的!就是「这是宏」的标记):条件为假就让程序以一种叫 panic 的方式立即终止, 报错信息里带出错位置。和 C/C++ 不同,Rust 的断言永远检查,与编译方式无关; 想在 release 构建里跳过断言,有另一个宏debug_assert!9。- 条件不加括号、大括号必填。
if m < n { … }——rustc甚至会为多余的括号发警告10。 - 函数的值是最后那个不带分号的表达式。
n不带分号,所以它是返回值;return只用于中途提前返回。更一般地,任何{ … }块都是表达式,值是块里最后一个表达式的值——这个决定在第 5 章会展开成「表达式语言」。
3.2 单元测试就住在源码里
给 gcd 配测试,不用测试框架,直接在 main.rs 末尾加:
#[test]
fn test_gcd() {
assert_eq!(gcd(14, 15), 1);
assert_eq!(gcd(2 * 3 * 54321, 5 * 7 * 54321), 54321);
}#[test] 是一个属性(attribute):给声明挂额外信息的开放机制(类比 C#/Java 的注解)。
它把 test_gcd 标记成测试函数——正常编译跳过它,cargo test 时自动收集、自动运行11。
测试可以散落在源码树各处、挨着被测代码放。
3.3 主线例子走一遍:cargo run 42 56
现在看完整的命令行程序,这是本章的主线例子:
use std::str::FromStr;
use std::env;
fn main() {
let mut numbers = Vec::new();
for arg in env::args().skip(1) {
numbers.push(u64::from_str(&arg).expect("error parsing argument"));
}
if numbers.len() == 0 {
eprintln!("Usage: gcd NUMBER ...");
std::process::exit(1);
}
let mut d = numbers[0];
for m in &numbers[1..] {
d = gcd(d, *m);
}
println!("The greatest common divisor of {numbers:?} is {d}");
}第一步:use 声明把名字引进来。
use std::str::FromStr; 引进一个叫 trait 的东西。trait 是一组方法的集合,类型可以实现它:
任何实现了 FromStr 的类型都有一个 from_str 方法,尝试从字符串解析(parse)出该类型的值12。
书里有句关键的话:就算代码里再没出现 FromStr 这个名字,trait 也必须在作用域内才能用它的方法——这个规矩以后会反复绊人。
第二步:Vec 与迭代器。
Vec::new() 建一个空向量;向量是可增长的数组(类比 C++ 的 std::vector、Python 的 list)。
类型 Vec<u64> 也不用写,Rust 从后面 push 进去的内容推断出来13。
env::args() 返回一个迭代器——按需逐个产生值、并知道什么时候完事的东西。
迭代器在 Rust 里无处不在(向量元素、文件的行、通道里的消息……),而且它有个承诺:
编译器通常能把 for 循环迭代器翻译成和手写的循环一样的机器码14。
迭代器还有一串方法可以直接用:.skip(1) 产生一个新迭代器,跳过头一个值——
头一个值永远是程序自己的名字,所以要跳过。
第三步:Result——Rust 的错误没有异常。
u64::from_str(&arg) 不直接返回 u64,返回一个 Result,它是两种形态之一:
| 形态 | 意思 |
|---|---|
Ok(v) | 解析成功,v 是得到的值 |
Err(e) | 失败,e 是解释原因的值 |
凡是可能失败的事(输入输出、和操作系统打交道)都返回 Result。
原书在这里下了一个全书级别的判断:Rust 没有异常,所有错误要么走 Result,要么走 panic15。
.expect("…") 是 Result 的方法:是 Err 就打印消息并退出程序;是 Ok(v) 就取出 v 给你16。
第四步:那两个奇怪的符号——& 和 *。
for m in &numbers[1..] { // & 干什么?
d = gcd(d, *m); // * 又干什么?
}遍历的向量可能很大,Rust 不想在你不知情的情况下复制或消耗它——它要你声明「这堆内存归谁、活多久」。
&numbers[1..] 的意思是:借用从第二个元素开始的引用,向量的所有权仍归 numbers;
m 挨个借用每个元素;*m 是解引用,取出它指向的那个 u64 交给 gcd17。
循环结束后 numbers 还拥有向量,Rust 在 main 结束时自动释放它。
这就是「借用」第一次出场。规则细节第 4 章讲,这里只需要记住:&x 借 x 的引用,*r 是引用 r 指向的值。
第五步:输出与退出码。
println! 是宏:模板字符串里的 {numbers:?} 被替换成变量的值,:? 表示按调试格式打印(带引号、转义)。
eprintln! 写到标准错误流。
退出码的约定和 C 相反:main 正常返回就算成功,想以错误退出必须显式调 std::process::exit(1) 或让 expect 失败18。
跑一次($ 是命令提示符,书里的输出实录):
$ cargo run 42 56
The greatest common divisor of [42, 56] is 14
$ cargo run
Usage: gcd NUMBER ...3.4 这一段立住了四个地基概念
回到主线例子的角色分配:FromStr 代表 trait;env::args() 代表迭代器;
expect 代表 Result 错误处理;&numbers[1..] 代表引用与借用。
这四个概念后面每一章都会用到,原书在第一章就全部埋下。
测试运行的实录
cargo test 的输出朴素而令人安心(书里的实录):一行「running 1 test」、
一行 test test_gcd ... ok、一行汇总「1 passed; 0 failed」。
测试函数就住在源码里、挨着被测代码,cargo test 自己把它们全找出来19。
4. 程序二:用第三方 crate 搭 web 服务
第二个程序还是那个 gcd,但用浏览器访问:页面让用户输入两个数,提交后服务器算结果。
这一节的主角不是程序本身,而是 crates.io——Rust 的免费开放包仓库,
cargo add actix-web 一条命令就把第三方库登记进 Cargo.toml,下载、构建、更新全由 cargo 包办20。
4.1 依赖、版本与 feature
Cargo.toml 的 [dependencies] 段每行写一个 crate 名加版本号。两个细节值得带走:
- 版本是「兼容范围内最新」:写
actix-web = "4.9.0",在新机器上构建或cargo update时, cargo 会取最新的兼容版本(比如 4.10.1)21。 - crate 可以有可选 feature:serde 的 derive 功能(等下要用)不是默认开启的,
必须写
serde = { version = "…", features = ["derive"] }显式申请22。
4.2 async:一个核伺候上千个连接
服务器长这样(骨架):
#[actix_web::main]
async fn main() {
let server = HttpServer::new(|| {
App::new()
.route("/", web::get().to(get_index))
});
server.bind("127.0.0.1:3000").expect("…").run().await.expect("…");
}两个新词。async fn,即异步(async)函数:等网络这种不耗 CPU 的时间可以让出来给别的任务,
一个 CPU 核就能灵敏地同时伺候上千个连接,不必为每个连接开一个系统线程。
它和 C#/JavaScript 的 async/await 同族23。机制细节(怎么实现的)书放在后面章节,本章只要会用。
闭包(closure):|| { App::new() … } 是一个可以像函数一样调用的值;
参数名写在两根竖线之间(这里没有参数)。Actix 为每个请求处理线程调用一次这个闭包,
拿到一份全新的 App 路由表24。
链式调用 .route(…) 返回的是被修改后的同一个 App;闭包体最后一行没有分号,
所以 App 是闭包的返回值——第 3 节「块的值」那条规定在闭包上原样生效。
4.3 derive:让编译器替你写代码
web 表单提交的是 n=42&m=56 这样的数据。处理函数想直接拿到一个 GcdParameters 结构体:
#[derive(Deserialize)]
struct GcdParameters { n: u64, m: u64, }#[derive(Deserialize)] 还是属性,但作用升级了:它让 serde 这个 crate 在编译时检查这个类型,
自动生成「从表单数据解析出 GcdParameters」的代码——JSON(一种常见的文本数据格式)、YAML、TOML 也都能解析25。
于是请求处理函数可以直接把 web::Form<GcdParameters> 声明为参数,
Actix 的类型系统保证:凡是不能从表单数据解析的类型,根本过不了编译26。
这里还顺带一个语法糖:结构体字段初始化可以简写成 Complex { re, im } 代替 Complex { re: re, im: im }(第 2 章的曼德博程序会用到);
而且 Rust 处处允许多余的尾逗号,多行列表以逗号收尾是标准风格——改动行时少碰标点,diff 更干净27。
原始字符串:HTML 的家
第一版服务器里那一大段 HTML 用的是原始字符串:r#"…"#——r 开头、两头用同样数量的
# 号包裹。原始字符串里不识别任何转义序列,双引号随便写,
所以满是属性的 HTML 不用每个引号都写 \"。唯一要想的是「结尾标记别在内容里提前出现」:
内容里有 "# 就用 r##"…"##,有几个井号保几层平安28。
post_gcd:校验、format! 与 400
处理表单提交的函数有两个细节值得收进笔记:
async fn post_gcd(form: web::Form<GcdParameters>) -> HttpResponse {
if form.n == 0 || form.m == 0 {
return HttpResponse::BadRequest() // HTTP 400
.content_type("text/html")
.body("Computing the GCD with zero is boring.");
}
let response = format!(
"The greatest common divisor of the numbers {} and {} is <b>{}</b>\n",
form.n, form.m, gcd(form.n, form.m),
);
HttpResponse::Ok().content_type("text/html").body(response)
}- 先做参数校验:gcd 遇到 0 会 panic,所以在边界上直接回 400,把「不可能的状态」挡在函数体外;
format!是println!的兄弟,不打印、返回字符串;要插值(把值填进字符串占位处)的不是简单变量名时, 用空{}占位、值按顺序作参数。返回值再被包进 HTTP 200 的响应体29。
路由注册就是把 .route("/gcd", web::post().to(post_gcd)) 再加一行——
GET 和 POST 各管一条路径,App 照旧是闭包的返回值30。
并发预告:你的第一个多线程程序已经写完了
本章最后一段(下一章的主角)先交代一个反直觉的事实:web 服务器就是那个多线程程序。 Actix 用线程池跑请求处理函数——同时来好几个请求,get_index 和 post_gcd 就可能在 好几个线程里同时执行。写这两个函数时我们脑子里完全没有并发,但 Rust 保证这安全: 「如果你的程序编译过了,它就是无数据竞争的。所有 Rust 函数都是线程安全的。」31
凭什么?眼下只能引用结论:第 3、4 章的规则会让「不安全的共享」编译不过。 本章只要带走这个反差——在别的语言里,这种「随手写、线程安全」是要花大钱买的; 在 Rust 里,它是编译通过的副产品。
5. 作者的判断与证据
这一章是「展示」,不是「论证」,但作者的判断仍然清晰可见:
- 「如果程序编译过了,它就是无数据竞争的」——这句话在并发一节出现,是全书最大胆的承诺。 证据不是这章给的:它引用的保证来自第 3、4 章的所有权/借用规则,这章只演示「你随手写的两个请求处理函数 可能同时跑在好几个线程上,而这是安全的」32。
- 「C 和 C++ 的并发名声很臭,Rust 把它洗白了」——作者明说这是他们的经验之谈, 特别是「数据搬去别的线程后,发送方还能不能摸到它」这种错,C 里要靠注释和自律,Rust 里编译器直接查33。
- 「我们强烈鼓励你去翻在线文档」——原书反复指你到 rustup 自带的离线标准库文档(
rustup doc --std), 这份文档连源码链接都有34。这是作者对读者学习路径的建议,不是广告。
哪些是推测:对 Actix、serde 这些第三方 crate 的选择是作者的口味(2025 年初的版本号); async 的性能承诺(「一个核伺候上千连接」)是框架的主张,原书没有在这章给出测量。
6. 边界与局限
- 版本即日期:cargo 1.85、actix-web 4.9、serde 1.0.217 都是 2025 年初的快照, 你今天照搬会得到更新的版本号;机制不变,数字会变。
- [Link to Come] 不是修辞:原书里
Cargo.toml 详解、trait 详解、async 详解全部挂着占位符—— Early Release 还没放出那些章节。 - web 程序的教学价值有限:它展示的是「Rust 在现实生态里怎么被使用」,但对理解 Rust 本身, 程序一和程序三的信息密度更高。
- 程序二没有讲错误处理的完整形态:
expect一出错就整个进程退出,真实服务器不会这样—— 怎么把错误传回给调用方层层处理,在还没放出的「错误处理」一章。
7. 可带走的
主线例子一行版: 命令行参数 → u64::from_str 解析(失败就 expect 退出)→ 迭代 &numbers[1..] 逐个借元素 →
循环调 gcd → println! 按调试格式打印。
- Rust 没有「看家特性」,全部设计服务于「安全的、高性能的系统编程」这一目标;
- 三个工具分工:cargo 管一切日常(建/编/跑/依赖),rustc 是编译器,rustdoc 出文档;
- 函数参数和返回值类型必写,函数体内靠类型推断;
- 变量默认不可变,要改加
mut——这是给读者的提示,不是累赘; assert!永远检查;panic 是 Rust 的「立即终止」,没有异常,错误走Result;expect是Result的「要么取值要么退出」;trait 必须在作用域内才能用它的方法;- 迭代器无处不在且零成本;
for x in &v是借用遍历,for x in v是消耗遍历; &借引用、*解引用;借用不转移所有权,所有者离开作用域时自动释放;- crate 是 Rust 的包;
Cargo.toml记依赖,feature 要显式开; #[derive(...)]让外部 crate 在编译期替你生成代码;#[test]让测试住在源码里。
8. 原文地图
| 主题 | 原书章 | 原文位置 |
|---|---|---|
| 没有单一特性、目标定位 | Chapter 1. A Tour of Rust | text/04-ch01-chapter-1-a-tour-of-rust.txt:13(搜「what gives the language its character」) |
| rustup 与三命令 | Chapter 1. A Tour of Rust | text/04-ch01-chapter-1-a-tour-of-rust.txt:29(搜「rustup.rs」) · text/04-ch01-chapter-1-a-tour-of-rust.txt:44(搜「compilation manager」) |
| cargo new、九行样板 | Chapter 1. A Tour of Rust | text/04-ch01-chapter-1-a-tour-of-rust.txt:95(搜「nine lines」) |
| gcd 函数语法 | Chapter 1. A Tour of Rust | text/04-ch01-chapter-1-a-tour-of-rust.txt:142(搜「fn keyword」) · text/04-ch01-chapter-1-a-tour-of-rust.txt:148(搜「panic」) · text/04-ch01-chapter-1-a-tour-of-rust.txt:156(搜「return statement」) |
| 单元测试与属性 | Chapter 1. A Tour of Rust | text/04-ch01-chapter-1-a-tour-of-rust.txt:175(搜「skipped in normal compilations」) · text/04-ch01-chapter-1-a-tour-of-rust.txt:177(搜「attribute」) |
| trait / FromStr | Chapter 1. A Tour of Rust | text/04-ch01-chapter-1-a-tour-of-rust.txt:224(搜「collection of methods」) |
| 迭代器与零成本 | Chapter 1. A Tour of Rust | text/04-ch01-chapter-1-a-tour-of-rust.txt:244(搜「on demand」) |
| Result、无异常 | Chapter 1. A Tour of Rust | text/04-ch01-chapter-1-a-tour-of-rust.txt:256(搜「does not have exceptions」) · text/04-ch01-chapter-1-a-tour-of-rust.txt:258(搜「expect」) |
& 与 *、自动释放 | Chapter 1. A Tour of Rust | text/04-ch01-chapter-1-a-tour-of-rust.txt:278(搜「borrows a reference」) |
| crate / crates.io / feature | Chapter 1. A Tour of Rust | text/04-ch01-chapter-1-a-tour-of-rust.txt:316(搜「freely available」) · text/04-ch01-chapter-1-a-tour-of-rust.txt:352(搜「latest compatible version」) · text/04-ch01-chapter-1-a-tour-of-rust.txt:354(搜「optional features」) |
| async 与闭包 | Chapter 1. A Tour of Rust | text/04-ch01-chapter-1-a-tour-of-rust.txt:395(搜「async」) · text/04-ch01-chapter-1-a-tour-of-rust.txt:399(搜「called as if it were a function」) |
| derive(Deserialize) | Chapter 1. A Tour of Rust | text/04-ch01-chapter-1-a-tour-of-rust.txt:446(搜「automatically generate」) |
| cargo 日常循环与 clean | Chapter 1. A Tour of Rust | text/04-ch01-chapter-1-a-tour-of-rust.txt:97(搜「cargo run」) · text/04-ch01-chapter-1-a-tour-of-rust.txt:120(搜「cargo clean」) |
| 测试运行实录 | Chapter 1. A Tour of Rust | text/04-ch01-chapter-1-a-tour-of-rust.txt:186(搜「running 1 test」) |
| post_gcd 与 format! | Chapter 1. A Tour of Rust | text/04-ch01-chapter-1-a-tour-of-rust.txt:454(搜「BadRequest」) |
| 并发预告:web 服务器即多线程 | Chapter 1. A Tour of Rust | text/04-ch01-chapter-1-a-tour-of-rust.txt:521(搜「pool of threads」) |
| 编译过即无数据竞争 | Chapter 1. A Tour of Rust | text/04-ch01-chapter-1-a-tour-of-rust.txt:521(搜「All Rust functions are thread-safe」) |
Footnotes
-
出处:「Chapter 1. A Tour of Rust」第 13 段(
text/04-ch01-chapter-1-a-tour-of-rust.txt:13,搜「what gives the language its character」)。 ↩ -
出处:「Chapter 1. A Tour of Rust」第 29–31 段(
text/04-ch01-chapter-1-a-tour-of-rust.txt:29-31,搜「RVM for Ruby」)。「像 RVM for Ruby 或 NVM for Node 一样管理 Rust 安装的工具」。 ↩ -
出处:「Chapter 1. A Tour of Rust」第 35–40 段(
text/04-ch01-chapter-1-a-tour-of-rust.txt:35-40,搜「cargo 1.85.0」)。 ↩ -
出处:「Chapter 1. A Tour of Rust」第 50–95 段(
text/04-ch01-chapter-1-a-tour-of-rust.txt:50-95,搜「two files, totaling nine lines」)。 ↩ -
出处:「Chapter 1. A Tour of Rust」第 316 段(
text/04-ch01-chapter-1-a-tour-of-rust.txt:316,搜「called a crate」)。 ↩ -
出处:「Chapter 1. A Tour of Rust」第 97–123 段(
text/04-ch01-chapter-1-a-tour-of-rust.txt:97-123,搜「cargo clean」)。 ↩ -
出处:「Chapter 1. A Tour of Rust」第 142–152 段(
text/04-ch01-chapter-1-a-tour-of-rust.txt:142-152,搜「fn keyword」与「infer」)。「Rust 只在函数体内推断类型:函数参数和返回值的类型必须写出。」 ↩ -
出处:「Chapter 1. A Tour of Rust」第 146 段(
text/04-ch01-chapter-1-a-tour-of-rust.txt:146,搜「helpful hint」)。 ↩ -
出处:「Chapter 1. A Tour of Rust」第 148 段(
text/04-ch01-chapter-1-a-tour-of-rust.txt:148,搜「always checks assertions」)。 ↩ -
出处:「Chapter 1. A Tour of Rust」第 150 段(
text/04-ch01-chapter-1-a-tour-of-rust.txt:150,搜「curly braces」)。 ↩ -
出处:「Chapter 1. A Tour of Rust」第 175 段(
text/04-ch01-chapter-1-a-tour-of-rust.txt:175,搜「skipped in normal compilations」)。 ↩ -
出处:「Chapter 1. A Tour of Rust」第 224 段(
text/04-ch01-chapter-1-a-tour-of-rust.txt:224,搜「collection of methods」)。 ↩ -
出处:「Chapter 1. A Tour of Rust」第 236–238 段(
text/04-ch01-chapter-1-a-tour-of-rust.txt:236-238,搜「growable vector」)。 ↩ -
出处:「Chapter 1. A Tour of Rust」第 244 段(
text/04-ch01-chapter-1-a-tour-of-rust.txt:244,搜「same code as a handwritten loop」)。 ↩ -
出处:「Chapter 1. A Tour of Rust」第 256 段(
text/04-ch01-chapter-1-a-tour-of-rust.txt:256,搜「does not have exceptions」)。 ↩ -
出处:「Chapter 1. A Tour of Rust」第 258 段(
text/04-ch01-chapter-1-a-tour-of-rust.txt:258,搜「exits the program immediately」)。 ↩ -
出处:「Chapter 1. A Tour of Rust」第 274–280 段(
text/04-ch01-chapter-1-a-tour-of-rust.txt:274-280,搜「complementary」与「borrows a reference」)。 ↩ -
出处:「Chapter 1. A Tour of Rust」第 288 段(
text/04-ch01-chapter-1-a-tour-of-rust.txt:288,搜「finished successfully」)。 ↩ -
出处:「Chapter 1. A Tour of Rust」第 179–190 段(
text/04-ch01-chapter-1-a-tour-of-rust.txt:179-190,搜「running 1 test」)。 ↩ -
出处:「Chapter 1. A Tour of Rust」第 316–318 段(
text/04-ch01-chapter-1-a-tour-of-rust.txt:316-318,搜「freely available」)。 ↩ -
出处:「Chapter 1. A Tour of Rust」第 352 段(
text/04-ch01-chapter-1-a-tour-of-rust.txt:352,搜「latest compatible version」)。 ↩ -
出处:「Chapter 1. A Tour of Rust」第 354 段(
text/04-ch01-chapter-1-a-tour-of-rust.txt:354,搜「optional features」)。 ↩ -
出处:「Chapter 1. A Tour of Rust」第 395 段(
text/04-ch01-chapter-1-a-tour-of-rust.txt:395,搜「C# and JavaScript」)。 ↩ -
出处:「Chapter 1. A Tour of Rust」第 399–401 段(
text/04-ch01-chapter-1-a-tour-of-rust.txt:399-401,搜「called as if it were a function」)。 ↩ -
出处:「Chapter 1. A Tour of Rust」第 446 段(
text/04-ch01-chapter-1-a-tour-of-rust.txt:446,搜「automatically generate」)。 ↩ -
出处:「Chapter 1. A Tour of Rust」第 472 段(
text/04-ch01-chapter-1-a-tour-of-rust.txt:472,搜「worked out at compile time」)。 ↩ -
出处:「Chapter 1. A Tour of Rust」第 448 段(
text/04-ch01-chapter-1-a-tour-of-rust.txt:448,搜「trailing comma」)。字段简写见「Parsing Pair Command-Line Arguments」第 97 段(text/06-fm-parsing-pair-command-line-arguments.txt:97,搜「shorthand」)。 ↩ -
出处:「Chapter 1. A Tour of Rust」第 405 段(
text/04-ch01-chapter-1-a-tour-of-rust.txt:405,搜「raw string」)。 ↩ -
出处:「Chapter 1. A Tour of Rust」第 452–474 段(
text/04-ch01-chapter-1-a-tour-of-rust.txt:452-474,搜「format!」)。 ↩ -
出处:「Chapter 1. A Tour of Rust」第 476–495 段(
text/04-ch01-chapter-1-a-tour-of-rust.txt:476-495,搜「/gcd」)。 ↩ -
出处:「Chapter 1. A Tour of Rust」第 519–521 段(
text/04-ch01-chapter-1-a-tour-of-rust.txt:519-521,搜「thread-safe」)。 ↩ -
出处:「Chapter 1. A Tour of Rust」第 521 段(
text/04-ch01-chapter-1-a-tour-of-rust.txt:521,搜「All Rust functions are thread-safe」)。 ↩ -
出处:「Chapter 1. A Tour of Rust」第 511–517 段(
text/04-ch01-chapter-1-a-tour-of-rust.txt:511-517,搜「left to the comments」)。三条对照(互斥锁、只读共享、所有权转移)里作者的原话:「不是我们要抱怨。」(Not that we're bitter.) ↩ -
出处:「Chapter 1. A Tour of Rust」第 310 段(
text/04-ch01-chapter-1-a-tour-of-rust.txt:310,搜「live search」)。 ↩