|
|
@ -1,8 +1,8 @@
|
|
|
|
## 变量和可变性
|
|
|
|
## 变量和可变性
|
|
|
|
|
|
|
|
|
|
|
|
> [ch03-01-variables-and-mutability.md](https://github.com/rust-lang/book/blob/main/src/ch03-01-variables-and-mutability.md)
|
|
|
|
> [ch03-01-variables-and-mutability.md](https://github.com/rust-lang/book/blob/main/src/ch03-01-variables-and-mutability.md)
|
|
|
|
> <br>
|
|
|
|
>
|
|
|
|
> commit 059f85014f2a96b7a2dcdc23e01c87ae319873bc
|
|
|
|
> commit 54164e99f7a1ad27fc6fc578783994513abd988d
|
|
|
|
|
|
|
|
|
|
|
|
正如第二章中[“使用变量储存值”][storing-values-with-variables]<!-- ignore --> 部分提到的那样,变量默认是不可改变的(immutable)。这是 Rust 提供给你的众多优势之一,让你得以充分利用 Rust 提供的安全性和简单并发性来编写代码。不过,你仍然可以使用可变变量。让我们探讨一下 Rust 为何及如何鼓励你利用不可变性,以及何时你会选择不使用不可变性。
|
|
|
|
正如第二章中[“使用变量储存值”][storing-values-with-variables]<!-- ignore --> 部分提到的那样,变量默认是不可改变的(immutable)。这是 Rust 提供给你的众多优势之一,让你得以充分利用 Rust 提供的安全性和简单并发性来编写代码。不过,你仍然可以使用可变变量。让我们探讨一下 Rust 为何及如何鼓励你利用不可变性,以及何时你会选择不使用不可变性。
|
|
|
|
|
|
|
|
|
|
|
@ -30,7 +30,7 @@
|
|
|
|
|
|
|
|
|
|
|
|
Rust 编译器保证,如果声明一个值不会变,它就真的不会变,所以你不必自己跟踪它。这意味着你的代码更易于推导。
|
|
|
|
Rust 编译器保证,如果声明一个值不会变,它就真的不会变,所以你不必自己跟踪它。这意味着你的代码更易于推导。
|
|
|
|
|
|
|
|
|
|
|
|
不过可变性也是非常有用的,可以用来更方便地编写代码。变量只是默认不可变;正如在第二章所做的那样,你可以在变量名之前加 `mut` 来使其可变。`mut` 也向读者表明了其他代码将会改变这个变量值的意图。
|
|
|
|
不过可变性也是非常有用的,可以用来更方便地编写代码。尽管变量默认是不可变的,你仍然可以在变量名前添加 `mut` 来使其可变,正如在第二章所做的那样。`mut` 也向读者表明了其他代码将会改变这个变量值的意图。
|
|
|
|
|
|
|
|
|
|
|
|
例如,让我们将 *src/main.rs* 修改为如下代码:
|
|
|
|
例如,让我们将 *src/main.rs* 修改为如下代码:
|
|
|
|
|
|
|
|
|
|
|
@ -46,7 +46,7 @@ Rust 编译器保证,如果声明一个值不会变,它就真的不会变,
|
|
|
|
{{#include ../listings/ch03-common-programming-concepts/no-listing-02-adding-mut/output.txt}}
|
|
|
|
{{#include ../listings/ch03-common-programming-concepts/no-listing-02-adding-mut/output.txt}}
|
|
|
|
```
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
通过 `mut`,允许把绑定到 `x` 的值从 `5` 改成 `6`。除了防止出现 bug 外,还有很多地方需要权衡取舍。例如,使用大型数据结构时,适当地使用可变变量,可能比复制和返回新分配的实例更快。对于较小的数据结构,总是创建新实例,采用更偏向函数式的编程风格,可能会使代码更易理解,为可读性而牺牲性能或许是值得的。
|
|
|
|
通过 `mut`,允许把绑定到 `x` 的值从 `5` 改成 `6`。是否让变量可变的最终决定权仍然在你,取决于在某个特定情况下,你是否认为变量可变会让代码更加清晰明了。
|
|
|
|
|
|
|
|
|
|
|
|
### 常量
|
|
|
|
### 常量
|
|
|
|
|
|
|
|
|
|
|
@ -72,9 +72,9 @@ const THREE_HOURS_IN_SECONDS: u32 = 60 * 60 * 3;
|
|
|
|
|
|
|
|
|
|
|
|
将遍布于应用程序中的硬编码值声明为常量,能帮助后来的代码维护人员了解值的意图。如果将来需要修改硬编码值,也只需修改汇聚于一处的硬编码值。
|
|
|
|
将遍布于应用程序中的硬编码值声明为常量,能帮助后来的代码维护人员了解值的意图。如果将来需要修改硬编码值,也只需修改汇聚于一处的硬编码值。
|
|
|
|
|
|
|
|
|
|
|
|
### 隐藏(Shadowing)
|
|
|
|
### 隐藏
|
|
|
|
|
|
|
|
|
|
|
|
正如在[第二章][comparing-the-guess-to-the-secret-number]猜猜看游戏中所讲,我们可以定义一个与之前变量同名的新变量。Rustacean 们称之为第一个变量被第二个 **隐藏** 了,这意味着程序使用这个变量时会看到第二个值。可以用相同变量名称来隐藏一个变量,以及重复使用 `let` 关键字来多次隐藏,如下所示:
|
|
|
|
正如在[第二章][comparing-the-guess-to-the-secret-number]猜数字游戏中所讲,我们可以定义一个与之前变量同名的新变量。Rustacean 们称之为第一个变量被第二个 **隐藏(Shadowing)** 了,这意味着当您使用变量的名称时,编译器将看到第二个变量。实际上,第二个变量“遮蔽”了第一个变量,此时任何使用该变量名的行为中都会视为是在使用第二个变量,直到第二个变量自己也被隐藏或第二个变量的作用域结束。可以用相同变量名称来隐藏一个变量,以及重复使用 `let` 关键字来多次隐藏,如下所示:
|
|
|
|
|
|
|
|
|
|
|
|
<span class="filename">文件名: src/main.rs</span>
|
|
|
|
<span class="filename">文件名: src/main.rs</span>
|
|
|
|
|
|
|
|
|
|
|
@ -82,7 +82,7 @@ const THREE_HOURS_IN_SECONDS: u32 = 60 * 60 * 3;
|
|
|
|
{{#rustdoc_include ../listings/ch03-common-programming-concepts/no-listing-03-shadowing/src/main.rs}}
|
|
|
|
{{#rustdoc_include ../listings/ch03-common-programming-concepts/no-listing-03-shadowing/src/main.rs}}
|
|
|
|
```
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
这个程序首先将 `x` 绑定到值 `5` 上。接着通过 `let x =` 隐藏 `x`,获取初始值并加 `1`,这样 `x` 的值就变成 `6` 了。然后,在内部作用域内,第三个 `let` 语句也隐藏了 `x`,将之前的值乘以 `2`,`x` 得到的值是 `12`。当该作用域结束时,内部 shadowing 的作用域也结束了,`x` 又返回到 `6`。运行这个程序,它会有如下输出:
|
|
|
|
这个程序首先将 `x` 绑定到值 `5` 上。接着通过 `let x =` 创建了一个新变量 `x`,获取初始值并加 `1`,这样 `x` 的值就变成 `6` 了。然后,在使用花括号创建的内部作用域内,第三个 `let` 语句也隐藏了 `x` 并创建了一个新的变量,将之前的值乘以 `2`,`x` 得到的值是 `12`。当该作用域结束时,内部 shadowing 的作用域也结束了,`x` 又返回到 `6`。运行这个程序,它会有如下输出:
|
|
|
|
|
|
|
|
|
|
|
|
```console
|
|
|
|
```console
|
|
|
|
{{#include ../listings/ch03-common-programming-concepts/no-listing-03-shadowing/output.txt}}
|
|
|
|
{{#include ../listings/ch03-common-programming-concepts/no-listing-03-shadowing/output.txt}}
|
|
|
|