diff --git a/README.md b/README.md index a78a7bb..e2c0c57 100644 --- a/README.md +++ b/README.md @@ -1 +1,9 @@ -# trpl-zh-cn \ No newline at end of file +# Rust 程序设计语言(第二版) 简体中文版 + +还在施工中... + +## Gitbook 中存在的问题 + +`
`中的 markdown 没有语法高亮QAQ + +[https://github.com/GitbookIO/gitbook/issues/1727](https://github.com/GitbookIO/gitbook/issues/1727) \ No newline at end of file diff --git a/docs/ch02-00-guessing-game-tutorial.html b/docs/ch02-00-guessing-game-tutorial.html index 751c0bd..c43699c 100644 --- a/docs/ch02-00-guessing-game-tutorial.html +++ b/docs/ch02-00-guessing-game-tutorial.html @@ -71,7 +71,7 @@

ch02-00-guessing-game-tutorial.md
-commit 77370c073661548dd56bbcb43cc64713585acbba

+commit 7c1c935560190fcd64c0851e75dbeabf75fedd19

让我们通过自己动手的方式一起完成一个项目来快速上手 Rust!本章通过展示如何在真实的项目中运用的方式向你介绍一些常用的 Rust 概念。你将会学到letmatch、方法、关联函数、使用外部 crate 等更多的知识!接下来的章节会探索这些概念的细节。在这一章,我们练习基础。

我们会实现一个经典新手编程问题:猜猜看游戏。它是这么工作的:程序将会随机生成一个 1 到 100 之间的随机整数。接着它会提示玩家输入一个猜测。当输入了一个猜测后,它会告诉提示猜测是太大了还是太小了。猜对了,它会打印出祝贺并退出。

@@ -128,10 +128,10 @@ fn main() {

Listing 2-1: Code to get a guess from the user and print it out

-

这些代码包含很多信息,所以让我们一点一点地过一遍。为了获取用户输入并接着打印结果作为输出,我们需要从标准库(被称为std)中引用io(输入/输出)库:

+

这些代码包含很多信息,所以让我们一点一点地过一遍。为了获取用户输入并接着打印结果作为输出,我们需要将io(输入/输出)库引入作用域中。io库来自于标准库(也被称为std):

use std::io;
 
-

Rust 默认只在每个程序的 prelude 中引用很少的一些类型。如果想要使用的类型并不在 prelude 中,你必须使用一个use语句显式的将其导入到程序中。使用std::io库将提供很多io相关的功能,接受用户输入的功能。

+

Rust 默认只在每个程序的 prelude 中引用很少的一些类型。如果想要使用的类型并不在 prelude 中,你必须使用一个use语句显式的将其引入到作用域中。使用std::io库将提供很多io相关的功能,接受用户输入的功能。

正如第一章所讲,main函数是程序的入口点:

fn main() {
 
@@ -300,7 +300,7 @@ fn main() {

我们在顶部增加一行extern crate rand;来让 Rust 知道我们要使用外部依赖。这也会调用相应的use rand,所以现在可以使用rand::前缀来调用rand中的任何内容。

接下来,我们增加了另一行useuse rand::RngRng是一个定义了随机数生成器应实现方法的 trait,如果要使用这些方法的话这个 trait 必须在作用域中。第十章会详细介绍 trait。

另外,中间还新增加了两行。rand::thread_rng函数会提供具体会使用的随机数生成器:它位于当前执行线程本地并从操作系统获取 seed。接下来,调用随机数生成器的gen_range方法。这个方法由我们使用use rand::Rng语句引入到作用域的Rng trait 定义。gen_range方法获取两个数作为参数并生成一个两者之间的随机数。它包含下限但不包含上限,所以需要指定1101来请求一个1100之间的数。

-

并不仅仅能够知道该引用哪个 trait 和该从 crate 中使用哪个方法。如何使用 crate 的说明在每个 crate 的文档中。Cargo 另一个很棒的功能是可以运行cargo doc --open命令来构建所有本地依赖提供的文档并在浏览器中打开。例如,如果你对rand crate 中的其他功能感兴趣,运行cargo doc --open并点击左侧导航栏的rand

+

并不仅仅能够知道该 use 哪个 trait 和该从 crate 中调用哪个方法。如何使用 crate 的说明在每个 crate 的文档中。Cargo 另一个很棒的功能是可以运行cargo doc --open命令来构建所有本地依赖提供的文档并在浏览器中打开。例如,如果你对rand crate 中的其他功能感兴趣,运行cargo doc --open并点击左侧导航栏的rand

新增加的第二行代码打印出了秘密数字。这在开发程序时很有用,因为我们可以去测试它,不过在最终版本我们会删掉它。游戏一开始就打印出结果就没什么可玩的了!

尝试运行程序几次:

$ cargo run
@@ -365,7 +365,7 @@ fn main() {
     Ordering::Equal   => println!("You win!"),
 }
 
-

cmp方法比较两个值并可以在任何可比较的值上调用。它获取一个任何你想要比较的值的引用:这里是把guesssecret_number做比较。cmp返回一个使用use语句引用的Ordering枚举的成员。我们使用一个match表达式根据对guesssecret_number中的值调用cmp后返回的哪个Ordering枚举成员来决定接下来干什么。

+

cmp方法比较两个值并可以在任何可比较的值上调用。它获取一个任何你想要比较的值的引用:这里是把guesssecret_number做比较。cmp返回一个使用use语句引入作用域的Ordering枚举的成员。我们使用一个match表达式根据对guesssecret_number中的值调用cmp后返回的哪个Ordering枚举成员来决定接下来干什么。

一个match表达式由 分支(arms) 构成。一个分支包含一个 模式pattern)和代码,这些代码在match表达式开头给出的值符合分支的模式时将被执行。Rust 获取提供给match的值并挨个检查每个分支的模式。match结构和模式是 Rust 中非常强大的功能,它帮助你体现代码可能遇到的多种情形并帮助你处理全部的可能。这些功能将分别在第六章和第十九章详细介绍。

让我们看看一个使用这里的match表达式会发生什么的例子。假设用户猜了 50,这时随机生成的秘密数字是 38。当代码比较 50 与 38 时,cmp方法会返回Ordering::Greater,因为 50 比 38 要大。Ordering::Greatermatch表达式得到的值。它检查第一个分支的模式,Ordering::Less,不过值Ordering::Greater并不匹配Ordering::Less。所以它忽略了这个分支的代码并移动到下一个分支。下一个分支的模式,Ordering::Greater正确匹配了Ordering::Greater!这个分支关联的代码会被执行并在屏幕打印出Too big!match表达式就此终止,因为在这个特定场景下没有检查最后一个分支的必要。

然而,列表 2-4 的代码并不能编译,尝试一下:

diff --git a/docs/ch03-02-data-types.html b/docs/ch03-02-data-types.html index 73e6cef..7d76713 100644 --- a/docs/ch03-02-data-types.html +++ b/docs/ch03-02-data-types.html @@ -71,17 +71,17 @@

ch03-02-data-types.md
-commit d05b7c63ff50b3f9126bb5533e0ba5dd424b83d1

+commit 6436ebee2a84820adf77231cead6b5691c8e2744

Rust 中的任何值都有一个具体的类型type),这告诉了 Rust 它被指定为何种数据这样 Rust 就知道如何处理这些数据了。这一部分将讲到一些语言内建的类型。我们将这些类型分为两个子集:标量(scalar)和复合(compound)。

贯穿整个部分,请记住 Rust 是一个静态类型statically typed)语言,也就是说必须在编译时就知道所有变量的类型。编译器通常可以通过值以及如何使用他们来推断出我们想要用的类型。当多个类型都是可能的时候,比如第二章中parseString转换为数字类型,必须增加类型注解,像这样:

-
let guess: u32 = "42".parse().unwrap();
+
let guess: u32 = "42".parse().expect("Not a number!");
 

如果这里不添加类型注解,Rust 会显示如下错误,它意味着编译器需要我们提供更多我们想要使用哪个可能的类型的信息:

error[E0282]: unable to infer enough type information about `_`
  --> src/main.rs:2:5
   |
-2 | let guess = "42".parse().unwrap();
+2 | let guess = "42".parse().expect("Not a number!");
   |     ^^^^^ cannot infer type for `_`
   |
   = note: type annotations or generic parameter binding required
diff --git a/docs/ch08-02-strings.html b/docs/ch08-02-strings.html
index 126e6af..6ced448 100644
--- a/docs/ch08-02-strings.html
+++ b/docs/ch08-02-strings.html
@@ -71,7 +71,7 @@
 

ch08-02-strings.md
-commit 4dc0001ccba4189e210ba47d6fe6c3c5fa729da6

+commit 65f52921e21ad2e1c79d620fcfd01bde3ee30571

第四章已经讲过一些字符串的内容,不过现在让我们更深入地了解一下它。字符串是新晋 Rustacean 们通常会被困住的领域。这是由于三方面内容的结合:Rust 倾向于确保暴露出可能的错误,字符串是比很多程序员所想象的要更为复杂的数据结构,以及 UTF-8。所有这些结合起来对于来自其他语言背景的程序员就可能显得很困难了。

字符串出现在集合章节的原因是,字符串是作为字节的集合外加一些方法实现的,当这些字节被解释为文本时,这些方法提供了实用的功能。在这一部分,我们会讲到String那些任何集合类型都有的操作,比如创建、更新和读取。也会讨论String于其他集合不一样的地方,例如索引String是很复杂的,由于人和计算机理解String数据的不同方式。

diff --git a/docs/ch12-01-accepting-command-line-arguments.html b/docs/ch12-01-accepting-command-line-arguments.html index af4a82f..7d8a15d 100644 --- a/docs/ch12-01-accepting-command-line-arguments.html +++ b/docs/ch12-01-accepting-command-line-arguments.html @@ -69,9 +69,9 @@

接受命令行参数

-

ch12-01-accepting-command-line-arguments.md +

ch12-01-accepting-command-line-arguments.md
-commit 2d32840aae46d247250310219e8c7169c7349017

+commit 4f2dc564851dc04b271a2260c834643dfd86c724

第一个任务是让greprs接受两个命令行参数。crates.io 上有一些现存的库可以帮助我们,不过因为我们正在学习,我们将自己实现一个。

我们需要调用一个 Rust 标准库提供的函数:std::env::args。这个函数返回一个传递给程序的命令行参数的迭代器iterator)。我们还未讨论到迭代器,第十三章会全面的介绍他们。但是对于我们的目的来说,使用他们并不需要知道多少技术细节。我们只需要明白两点:

@@ -104,7 +104,28 @@ $ cargo run needle haystack ...snip... ["target/debug/greprs", "needle", "haystack"]
-

你会注意一个有趣的事情:二进制文件的名字是第一个参数。其原因超出了本章介绍的范围

+

你会注意一个有趣的事情:二进制文件的名字是第一个参数。其原因超出了本章介绍的范围,不过这是我们必须记住的。

+

现在我们有了一个访问所有参数的方法,让我们如列表 12-2 中所示将需要的变量存放到变量中:

+
+Filename: src/main.rs +
use std::env;
+
+fn main() {
+    let args: Vec<String> = env::args().collect();
+
+    let search = &args[1];
+    let filename = &args[2];
+
+    println!("Searching for {}", search);
+    println!("In file {}", filename);
+}
+
+
+

Listing 12-2: Create variables to hold the search argument and filename argument

+
+
+ +

记住,程序名称是是第一个参数,所以并不需要args[0]。我们决定从第一个参数将是需要搜索的字符串,所以

diff --git a/docs/print.html b/docs/print.html index 76d5081..1b83cc7 100644 --- a/docs/print.html +++ b/docs/print.html @@ -285,7 +285,7 @@ $ carg

ch02-00-guessing-game-tutorial.md
-commit 77370c073661548dd56bbcb43cc64713585acbba

+commit 7c1c935560190fcd64c0851e75dbeabf75fedd19

让我们通过自己动手的方式一起完成一个项目来快速上手 Rust!本章通过展示如何在真实的项目中运用的方式向你介绍一些常用的 Rust 概念。你将会学到letmatch、方法、关联函数、使用外部 crate 等更多的知识!接下来的章节会探索这些概念的细节。在这一章,我们练习基础。

我们会实现一个经典新手编程问题:猜猜看游戏。它是这么工作的:程序将会随机生成一个 1 到 100 之间的随机整数。接着它会提示玩家输入一个猜测。当输入了一个猜测后,它会告诉提示猜测是太大了还是太小了。猜对了,它会打印出祝贺并退出。

@@ -342,10 +342,10 @@ fn main() {

Listing 2-1: Code to get a guess from the user and print it out

-

这些代码包含很多信息,所以让我们一点一点地过一遍。为了获取用户输入并接着打印结果作为输出,我们需要从标准库(被称为std)中引用io(输入/输出)库:

+

这些代码包含很多信息,所以让我们一点一点地过一遍。为了获取用户输入并接着打印结果作为输出,我们需要将io(输入/输出)库引入作用域中。io库来自于标准库(也被称为std):

use std::io;
 
-

Rust 默认只在每个程序的 prelude 中引用很少的一些类型。如果想要使用的类型并不在 prelude 中,你必须使用一个use语句显式的将其导入到程序中。使用std::io库将提供很多io相关的功能,接受用户输入的功能。

+

Rust 默认只在每个程序的 prelude 中引用很少的一些类型。如果想要使用的类型并不在 prelude 中,你必须使用一个use语句显式的将其引入到作用域中。使用std::io库将提供很多io相关的功能,接受用户输入的功能。

正如第一章所讲,main函数是程序的入口点:

fn main() {
 
@@ -514,7 +514,7 @@ fn main() {

我们在顶部增加一行extern crate rand;来让 Rust 知道我们要使用外部依赖。这也会调用相应的use rand,所以现在可以使用rand::前缀来调用rand中的任何内容。

接下来,我们增加了另一行useuse rand::RngRng是一个定义了随机数生成器应实现方法的 trait,如果要使用这些方法的话这个 trait 必须在作用域中。第十章会详细介绍 trait。

另外,中间还新增加了两行。rand::thread_rng函数会提供具体会使用的随机数生成器:它位于当前执行线程本地并从操作系统获取 seed。接下来,调用随机数生成器的gen_range方法。这个方法由我们使用use rand::Rng语句引入到作用域的Rng trait 定义。gen_range方法获取两个数作为参数并生成一个两者之间的随机数。它包含下限但不包含上限,所以需要指定1101来请求一个1100之间的数。

-

并不仅仅能够知道该引用哪个 trait 和该从 crate 中使用哪个方法。如何使用 crate 的说明在每个 crate 的文档中。Cargo 另一个很棒的功能是可以运行cargo doc --open命令来构建所有本地依赖提供的文档并在浏览器中打开。例如,如果你对rand crate 中的其他功能感兴趣,运行cargo doc --open并点击左侧导航栏的rand

+

并不仅仅能够知道该 use 哪个 trait 和该从 crate 中调用哪个方法。如何使用 crate 的说明在每个 crate 的文档中。Cargo 另一个很棒的功能是可以运行cargo doc --open命令来构建所有本地依赖提供的文档并在浏览器中打开。例如,如果你对rand crate 中的其他功能感兴趣,运行cargo doc --open并点击左侧导航栏的rand

新增加的第二行代码打印出了秘密数字。这在开发程序时很有用,因为我们可以去测试它,不过在最终版本我们会删掉它。游戏一开始就打印出结果就没什么可玩的了!

尝试运行程序几次:

$ cargo run
@@ -579,7 +579,7 @@ fn main() {
     Ordering::Equal   => println!("You win!"),
 }
 
-

cmp方法比较两个值并可以在任何可比较的值上调用。它获取一个任何你想要比较的值的引用:这里是把guesssecret_number做比较。cmp返回一个使用use语句引用的Ordering枚举的成员。我们使用一个match表达式根据对guesssecret_number中的值调用cmp后返回的哪个Ordering枚举成员来决定接下来干什么。

+

cmp方法比较两个值并可以在任何可比较的值上调用。它获取一个任何你想要比较的值的引用:这里是把guesssecret_number做比较。cmp返回一个使用use语句引入作用域的Ordering枚举的成员。我们使用一个match表达式根据对guesssecret_number中的值调用cmp后返回的哪个Ordering枚举成员来决定接下来干什么。

一个match表达式由 分支(arms) 构成。一个分支包含一个 模式pattern)和代码,这些代码在match表达式开头给出的值符合分支的模式时将被执行。Rust 获取提供给match的值并挨个检查每个分支的模式。match结构和模式是 Rust 中非常强大的功能,它帮助你体现代码可能遇到的多种情形并帮助你处理全部的可能。这些功能将分别在第六章和第十九章详细介绍。

让我们看看一个使用这里的match表达式会发生什么的例子。假设用户猜了 50,这时随机生成的秘密数字是 38。当代码比较 50 与 38 时,cmp方法会返回Ordering::Greater,因为 50 比 38 要大。Ordering::Greatermatch表达式得到的值。它检查第一个分支的模式,Ordering::Less,不过值Ordering::Greater并不匹配Ordering::Less。所以它忽略了这个分支的代码并移动到下一个分支。下一个分支的模式,Ordering::Greater正确匹配了Ordering::Greater!这个分支关联的代码会被执行并在屏幕打印出Too big!match表达式就此终止,因为在这个特定场景下没有检查最后一个分支的必要。

然而,列表 2-4 的代码并不能编译,尝试一下:

@@ -949,17 +949,17 @@ spaces = spaces.len();

ch03-02-data-types.md
-commit d05b7c63ff50b3f9126bb5533e0ba5dd424b83d1

+commit 6436ebee2a84820adf77231cead6b5691c8e2744

Rust 中的任何值都有一个具体的类型type),这告诉了 Rust 它被指定为何种数据这样 Rust 就知道如何处理这些数据了。这一部分将讲到一些语言内建的类型。我们将这些类型分为两个子集:标量(scalar)和复合(compound)。

贯穿整个部分,请记住 Rust 是一个静态类型statically typed)语言,也就是说必须在编译时就知道所有变量的类型。编译器通常可以通过值以及如何使用他们来推断出我们想要用的类型。当多个类型都是可能的时候,比如第二章中parseString转换为数字类型,必须增加类型注解,像这样:

-
let guess: u32 = "42".parse().unwrap();
+
let guess: u32 = "42".parse().expect("Not a number!");
 

如果这里不添加类型注解,Rust 会显示如下错误,它意味着编译器需要我们提供更多我们想要使用哪个可能的类型的信息:

error[E0282]: unable to infer enough type information about `_`
  --> src/main.rs:2:5
   |
-2 | let guess = "42".parse().unwrap();
+2 | let guess = "42".parse().expect("Not a number!");
   |     ^^^^^ cannot infer type for `_`
   |
   = note: type annotations or generic parameter binding required
@@ -3815,7 +3815,7 @@ let row = vec![
 

ch08-02-strings.md
-commit 4dc0001ccba4189e210ba47d6fe6c3c5fa729da6

+commit 65f52921e21ad2e1c79d620fcfd01bde3ee30571

第四章已经讲过一些字符串的内容,不过现在让我们更深入地了解一下它。字符串是新晋 Rustacean 们通常会被困住的领域。这是由于三方面内容的结合:Rust 倾向于确保暴露出可能的错误,字符串是比很多程序员所想象的要更为复杂的数据结构,以及 UTF-8。所有这些结合起来对于来自其他语言背景的程序员就可能显得很困难了。

字符串出现在集合章节的原因是,字符串是作为字节的集合外加一些方法实现的,当这些字节被解释为文本时,这些方法提供了实用的功能。在这一部分,我们会讲到String那些任何集合类型都有的操作,比如创建、更新和读取。也会讨论String于其他集合不一样的地方,例如索引String是很复杂的,由于人和计算机理解String数据的不同方式。

@@ -6132,9 +6132,9 @@ $ cd greprs

我们版本的grep的叫做“greprs”,这样就不会迷惑用户让他们以为这就是可能已经在系统上安装了功能更完整的grep

接受命令行参数

-

ch12-01-accepting-command-line-arguments.md +

ch12-01-accepting-command-line-arguments.md
-commit 2d32840aae46d247250310219e8c7169c7349017

+commit 4f2dc564851dc04b271a2260c834643dfd86c724

第一个任务是让greprs接受两个命令行参数。crates.io 上有一些现存的库可以帮助我们,不过因为我们正在学习,我们将自己实现一个。

我们需要调用一个 Rust 标准库提供的函数:std::env::args。这个函数返回一个传递给程序的命令行参数的迭代器iterator)。我们还未讨论到迭代器,第十三章会全面的介绍他们。但是对于我们的目的来说,使用他们并不需要知道多少技术细节。我们只需要明白两点:

@@ -6167,7 +6167,28 @@ $ cargo run needle haystack ...snip... ["target/debug/greprs", "needle", "haystack"]
-

你会注意一个有趣的事情:二进制文件的名字是第一个参数。其原因超出了本章介绍的范围

+

你会注意一个有趣的事情:二进制文件的名字是第一个参数。其原因超出了本章介绍的范围,不过这是我们必须记住的。

+

现在我们有了一个访问所有参数的方法,让我们如列表 12-2 中所示将需要的变量存放到变量中:

+
+Filename: src/main.rs +
use std::env;
+
+fn main() {
+    let args: Vec<String> = env::args().collect();
+
+    let search = &args[1];
+    let filename = &args[2];
+
+    println!("Searching for {}", search);
+    println!("In file {}", filename);
+}
+
+
+

Listing 12-2: Create variables to hold the search argument and filename argument

+
+
+ +

记住,程序名称是是第一个参数,所以并不需要args[0]。我们决定从第一个参数将是需要搜索的字符串,所以

diff --git a/src/ch02-00-guessing-game-tutorial.md b/src/ch02-00-guessing-game-tutorial.md index 06a633b..9dbdab7 100644 --- a/src/ch02-00-guessing-game-tutorial.md +++ b/src/ch02-00-guessing-game-tutorial.md @@ -2,7 +2,7 @@ > [ch02-00-guessing-game-tutorial.md](https://github.com/rust-lang/book/blob/master/src/ch02-00-guessing-game-tutorial.md) >
-> commit 77370c073661548dd56bbcb43cc64713585acbba +> commit 7c1c935560190fcd64c0851e75dbeabf75fedd19 让我们通过自己动手的方式一起完成一个项目来快速上手 Rust!本章通过展示如何在真实的项目中运用的方式向你介绍一些常用的 Rust 概念。你将会学到`let`、`match`、方法、关联函数、使用外部 crate 等更多的知识!接下来的章节会探索这些概念的细节。在这一章,我们练习基础。 @@ -89,13 +89,13 @@ Listing 2-1: Code to get a guess from the user and print it out -这些代码包含很多信息,所以让我们一点一点地过一遍。为了获取用户输入并接着打印结果作为输出,我们需要从标准库(被称为`std`)中引用`io`(输入/输出)库: +这些代码包含很多信息,所以让我们一点一点地过一遍。为了获取用户输入并接着打印结果作为输出,我们需要将`io`(输入/输出)库引入作用域中。`io`库来自于标准库(也被称为`std`): ```rust,ignore use std::io; ``` -Rust 默认只在每个程序的 [*prelude*][prelude] 中引用很少的一些类型。如果想要使用的类型并不在 prelude 中,你必须使用一个`use`语句显式的将其导入到程序中。使用`std::io`库将提供很多`io`相关的功能,接受用户输入的功能。 +Rust 默认只在每个程序的 [*prelude*][prelude] 中引用很少的一些类型。如果想要使用的类型并不在 prelude 中,你必须使用一个`use`语句显式的将其引入到作用域中。使用`std::io`库将提供很多`io`相关的功能,接受用户输入的功能。 [prelude]: https://doc.rust-lang.org/std/prelude/ @@ -393,7 +393,7 @@ Listing 2-3: Code changes needed in order to generate a random number 另外,中间还新增加了两行。`rand::thread_rng`函数会提供具体会使用的随机数生成器:它位于当前执行线程本地并从操作系统获取 seed。接下来,调用随机数生成器的`gen_range`方法。这个方法由我们使用`use rand::Rng`语句引入到作用域的`Rng` trait 定义。`gen_range`方法获取两个数作为参数并生成一个两者之间的随机数。它包含下限但不包含上限,所以需要指定`1`和`101`来请求一个`1`和`100`之间的数。 -并不仅仅能够知道该引用哪个 trait 和该从 crate 中使用哪个方法。如何使用 crate 的说明在每个 crate 的文档中。Cargo 另一个很棒的功能是可以运行`cargo doc --open`命令来构建所有本地依赖提供的文档并在浏览器中打开。例如,如果你对`rand` crate 中的其他功能感兴趣,运行`cargo doc --open`并点击左侧导航栏的`rand`。 +并不仅仅能够知道该 use 哪个 trait 和该从 crate 中调用哪个方法。如何使用 crate 的说明在每个 crate 的文档中。Cargo 另一个很棒的功能是可以运行`cargo doc --open`命令来构建所有本地依赖提供的文档并在浏览器中打开。例如,如果你对`rand` crate 中的其他功能感兴趣,运行`cargo doc --open`并点击左侧导航栏的`rand`。 新增加的第二行代码打印出了秘密数字。这在开发程序时很有用,因为我们可以去测试它,不过在最终版本我们会删掉它。游戏一开始就打印出结果就没什么可玩的了! @@ -476,7 +476,7 @@ match guess.cmp(&secret_number) { } ``` -`cmp`方法比较两个值并可以在任何可比较的值上调用。它获取一个任何你想要比较的值的引用:这里是把`guess`与`secret_number`做比较。`cmp`返回一个使用`use`语句引用的`Ordering`枚举的成员。我们使用一个[`match`][match]表达式根据对`guess`和`secret_number`中的值调用`cmp`后返回的哪个`Ordering`枚举成员来决定接下来干什么。 +`cmp`方法比较两个值并可以在任何可比较的值上调用。它获取一个任何你想要比较的值的引用:这里是把`guess`与`secret_number`做比较。`cmp`返回一个使用`use`语句引入作用域的`Ordering`枚举的成员。我们使用一个[`match`][match]表达式根据对`guess`和`secret_number`中的值调用`cmp`后返回的哪个`Ordering`枚举成员来决定接下来干什么。 [match]: ch06-02-match.html diff --git a/src/ch03-02-data-types.md b/src/ch03-02-data-types.md index b5f24c5..4ec5967 100644 --- a/src/ch03-02-data-types.md +++ b/src/ch03-02-data-types.md @@ -2,14 +2,14 @@ > [ch03-02-data-types.md](https://github.com/rust-lang/book/blob/master/src/ch03-02-data-types.md) >
-> commit d05b7c63ff50b3f9126bb5533e0ba5dd424b83d1 +> commit 6436ebee2a84820adf77231cead6b5691c8e2744 Rust 中的任何值都有一个具体的**类型**(*type*),这告诉了 Rust 它被指定为何种数据这样 Rust 就知道如何处理这些数据了。这一部分将讲到一些语言内建的类型。我们将这些类型分为两个子集:标量(scalar)和复合(compound)。 贯穿整个部分,请记住 Rust 是一个**静态类型**(*statically typed*)语言,也就是说必须在编译时就知道所有变量的类型。编译器通常可以通过值以及如何使用他们来推断出我们想要用的类型。当多个类型都是可能的时候,比如第二章中`parse`将`String`转换为数字类型,必须增加类型注解,像这样: ```rust -let guess: u32 = "42".parse().unwrap(); +let guess: u32 = "42".parse().expect("Not a number!"); ``` 如果这里不添加类型注解,Rust 会显示如下错误,它意味着编译器需要我们提供更多我们想要使用哪个可能的类型的信息: @@ -18,7 +18,7 @@ let guess: u32 = "42".parse().unwrap(); error[E0282]: unable to infer enough type information about `_` --> src/main.rs:2:5 | -2 | let guess = "42".parse().unwrap(); +2 | let guess = "42".parse().expect("Not a number!"); | ^^^^^ cannot infer type for `_` | = note: type annotations or generic parameter binding required diff --git a/src/ch08-02-strings.md b/src/ch08-02-strings.md index 222f9d2..811681d 100644 --- a/src/ch08-02-strings.md +++ b/src/ch08-02-strings.md @@ -2,7 +2,7 @@ > [ch08-02-strings.md](https://github.com/rust-lang/book/blob/master/src/ch08-02-strings.md) >
-> commit 4dc0001ccba4189e210ba47d6fe6c3c5fa729da6 +> commit 65f52921e21ad2e1c79d620fcfd01bde3ee30571 第四章已经讲过一些字符串的内容,不过现在让我们更深入地了解一下它。字符串是新晋 Rustacean 们通常会被困住的领域。这是由于三方面内容的结合:Rust 倾向于确保暴露出可能的错误,字符串是比很多程序员所想象的要更为复杂的数据结构,以及 UTF-8。所有这些结合起来对于来自其他语言背景的程序员就可能显得很困难了。 diff --git a/src/ch12-01-accepting-command-line-arguments.md b/src/ch12-01-accepting-command-line-arguments.md index 512e61e..4da612d 100644 --- a/src/ch12-01-accepting-command-line-arguments.md +++ b/src/ch12-01-accepting-command-line-arguments.md @@ -1,8 +1,8 @@ ## 接受命令行参数 -> [ch12-01-accepting-command-line-arguments.md](https://github.com/rust-lang/book/blob/master/src/ch12-01-accepting-command-line-arguments.md) +> [ch12-01-accepting-command-line-arguments.md](https://github.com/rust-lang/book/blob/master/second-edition/src/ch12-01-accepting-command-line-arguments.md) >
-> commit 2d32840aae46d247250310219e8c7169c7349017 +> commit 4f2dc564851dc04b271a2260c834643dfd86c724 第一个任务是让`greprs`接受两个命令行参数。crates.io 上有一些现存的库可以帮助我们,不过因为我们正在学习,我们将自己实现一个。 @@ -49,4 +49,34 @@ $ cargo run needle haystack ["target/debug/greprs", "needle", "haystack"] ``` -你会注意一个有趣的事情:二进制文件的名字是第一个参数。其原因超出了本章介绍的范围 \ No newline at end of file +你会注意一个有趣的事情:二进制文件的名字是第一个参数。其原因超出了本章介绍的范围,不过这是我们必须记住的。 + +现在我们有了一个访问所有参数的方法,让我们如列表 12-2 中所示将需要的变量存放到变量中: + +
+Filename: src/main.rs + +```rust +use std::env; + +fn main() { + let args: Vec = env::args().collect(); + + let search = &args[1]; + let filename = &args[2]; + + println!("Searching for {}", search); + println!("In file {}", filename); +} +``` + +
+ +Listing 12-2: Create variables to hold the search argument and filename argument + +
+
+ + + +记住,程序名称是是第一个参数,所以并不需要`args[0]`。我们决定从第一个参数将是需要搜索的字符串,所以 \ No newline at end of file