diff --git a/src/ch01-02-hello-world.md b/src/ch01-02-hello-world.md index 6d24807..65b7a6f 100644 --- a/src/ch01-02-hello-world.md +++ b/src/ch01-02-hello-world.md @@ -123,7 +123,7 @@ $ ./main # or .\main.exe on Windows Cargo 是 Rust 的构建系统和包管理工具,同时 Rustacean 们使用 Cargo 来管理他们的 Rust 项目,因为它使得很多任务变得更轻松。例如,Cargo 负责构建代码、下载代码依赖的库并编译这些库。我们把代码需要的库叫做 **依赖**(*dependencies*)。 -最简单的 Rust 程序,例如我们刚刚编写的,并没有任何依赖,所以目前我们只使用了 Cargo 负责构建代码的那一部分。随着编写更加复杂的 Rust 程序,你会想要添加依赖,那么如果你使用 Cargo 开始的话,这将会变得简单许多。 +最简单的 Rust 程序,例如我们刚刚编写的,并没有任何依赖,所以目前我们只使用了 Cargo 负责构建代码的那一部分。随着编写更加复杂的 Rust 程序,你会想要添加依赖,如果你使用 Cargo 开始的话,这将会变得简单许多。 由于绝大部分 Rust 项目使用 Cargo,本书接下来的部分将假设你使用它。如果使用安装章节介绍的官方安装包的话,Rust 自带 Cargo。如果通过其他方式安装 Rust 的话,可以在终端输入如下命令检查是否安装了 Cargo: diff --git a/src/ch04-02-references-and-borrowing.md b/src/ch04-02-references-and-borrowing.md index a8bf6ad..6cbbcbe 100644 --- a/src/ch04-02-references-and-borrowing.md +++ b/src/ch04-02-references-and-borrowing.md @@ -58,7 +58,7 @@ fn calculate_length(s: &String) -> usize { // s is a reference to a String 我们将获取引用作为函数参数称为**借用**(*borrowing*)。正如现实生活中,如果一个人拥有某样东西,你可以从它哪里借来。当你使用完毕,必须还回去。 -那么如果我们尝试修改借用的变量呢?尝试列表 4-9 中的代码。剧透:这行不通! +如果我们尝试修改借用的变量呢?尝试列表 4-9 中的代码。剧透:这行不通! Filename: src/main.rs diff --git a/src/ch08-02-strings.md b/src/ch08-02-strings.md index 15d8e58..927a6dc 100644 --- a/src/ch08-02-strings.md +++ b/src/ch08-02-strings.md @@ -223,7 +223,7 @@ let s = &hello[0..4]; 这里,`s`是一个`&str`,它包含字符串的头四个字节。早些时候,我们提到了这些字母都是两个字节长的,所以这意味着`s`将会是“Зд”。 -那么如果获取`&hello[0..1]`会发生什么呢?回答是:在运行时会 panic,就跟访问 vector 中的无效索引时一样: +如果获取`&hello[0..1]`会发生什么呢?回答是:在运行时会 panic,就跟访问 vector 中的无效索引时一样: ```text diff --git a/src/ch16-03-shared-state.md b/src/ch16-03-shared-state.md index b050e0c..5ef8f80 100644 --- a/src/ch16-03-shared-state.md +++ b/src/ch16-03-shared-state.md @@ -258,11 +258,11 @@ std::marker::Send` is not satisfied 哇哦,太长不看!说重点:第一个提示表明 `Rc>` 不能安全的在线程间传递。理由也在错误信息中,“不满足 `Send` trait bound”(`the trait bound Send is not satisfied`)。下一部分将会讨论 `Send`,它是确保许多用在多线程中的类型,能够适合并发环境的 trait 之一。 -不幸的是,`Rc` 并不能安全的在线程间共享。当 `Rc` 管理引用计数时,它必须在每一个 `clone` 调用时增加计数,并在每一个克隆被丢弃时减少计数。`Rc` 并没有使用任何并发原语,来确保改变计数的操作不会被其他线程打断。在计数出错时可能会导致诡异的 bug,比如可能会造成内存泄漏,或在使用结束之前就丢弃一个值。那么如果有一个正好与 `Rc` 类似,而又以一种线程安全的方式改变引用计数的类型会怎么样呢? +不幸的是,`Rc` 并不能安全的在线程间共享。当 `Rc` 管理引用计数时,它必须在每一个 `clone` 调用时增加计数,并在每一个克隆被丢弃时减少计数。`Rc` 并没有使用任何并发原语,来确保改变计数的操作不会被其他线程打断。在计数出错时可能会导致诡异的 bug,比如可能会造成内存泄漏,或在使用结束之前就丢弃一个值。如果有一个类型与 `Rc` 相似,又以一种线程安全的方式改变引用计数,会怎么样呢? #### 原子引用计数 `Arc` -如果你想过之前的问题,答案是肯定的,确实有一个类似`Rc`并可以安全的用于并发环境的类型:`Arc`。字母“a”代表**原子性**(*atomic*),所以这是一个**原子引用计数**(*atomically reference counted*)类型。原子性是另一类这里还未涉及到的并发原语;请查看标准库中`std::sync::atomic`的文档来获取更多细节。其中的要点就是:原子性类型工作起来类似原始类型,不过可以安全的在线程间共享。 +答案是肯定的,确实有一个类似`Rc`并可以安全的用于并发环境的类型:`Arc`。字母“a”代表**原子性**(*atomic*),所以这是一个**原子引用计数**(*atomically reference counted*)类型。原子性是另一类这里还未涉及到的并发原语;请查看标准库中`std::sync::atomic`的文档来获取更多细节。其中的要点就是:原子性类型工作起来类似原始类型,不过可以安全的在线程间共享。 为什么不是所有的原始类型都是原子性的?为什么不是所有标准库中的类型都默认使用`Arc`实现?线程安全带来性能惩罚,我们希望只在必要时才为此买单。如果只是在单线程中对值进行操作,原子性提供的保证并无必要,代码可以因此运行的更快。