mirror of
https://github.com/KaiserY/trpl-zh-cn
synced 2024-11-09 08:51:18 +08:00
commit
cab5499d60
@ -42,7 +42,7 @@
|
||||
|
||||
### 读取 vector 的元素
|
||||
|
||||
现在你知道如何创建、更新和销毁 vector 了,接下来的一步最好了解一下如何读取它们的内容。有两种方法引用 vector 中储存的值。为了更加清楚的说明这个例子,我们标注这些函数返回的值的类型。
|
||||
有两种方法引用 vector 中储存的值:通过索引或使用 `get` 方法。在接下来的示例中,为了更加清楚的说明,我们已经标注了这些函数返回的值的类型。
|
||||
|
||||
示例 8-4 展示了访问 vector 中一个值的两种方式,索引语法或者 `get` 方法:
|
||||
|
||||
@ -110,7 +110,7 @@ Rust 提供了两种引用元素的方法的原因是当尝试使用现有元素
|
||||
|
||||
vector 只能储存相同类型的值。这是很不方便的;绝对会有需要储存一系列不同类型的值的用例。幸运的是,枚举的成员都被定义为相同的枚举类型,所以当需要在 vector 中储存不同类型值时,我们可以定义并使用一个枚举!
|
||||
|
||||
例如,假如我们想要从电子表格的一行中获取值,而这一行的有些列包含数字,有些包含浮点值,还有些是字符串。我们可以定义一个枚举,其成员会存放这些不同类型的值,同时所有这些枚举成员都会被当作相同类型,那个枚举的类型。接着可以创建一个储存枚举值的 vector,这样最终就能够储存不同类型的值了。示例 8-9 展示了其用例:
|
||||
例如,假如我们想要从电子表格的一行中获取值,而这一行的有些列包含数字,有些包含浮点值,还有些是字符串。我们可以定义一个枚举,其成员会存放这些不同类型的值,同时所有这些枚举成员都会被当作相同类型:那个枚举的类型。接着可以创建一个储存枚举值的 vector,这样最终就能够储存不同类型的值了。示例 8-9 展示了其用例:
|
||||
|
||||
```rust
|
||||
{{#rustdoc_include ../listings/ch08-common-collections/listing-08-09/src/main.rs:here}}
|
||||
@ -136,9 +136,6 @@ Rust 在编译时就必须准确的知道 vector 中类型的原因在于它需
|
||||
|
||||
当 vector 被丢弃时,所有其内容也会被丢弃,这意味着这里它包含的整数将被清理。借用检查器确保了任何 vector 中内容的引用仅在 vector 本身有效时才可用。
|
||||
|
||||
|
||||
这可能看起来非常直观,不过一旦开始使用 vector 元素的引用,情况就变得有些复杂了。下面让我们处理这种情况!
|
||||
|
||||
让我们继续下一个集合类型:`String`!
|
||||
|
||||
[data-types]: ch03-02-data-types.html#数据类型
|
||||
|
@ -22,7 +22,7 @@
|
||||
|
||||
<span class="caption">示例 8-11:新建一个空的 `String`</span>
|
||||
|
||||
这新建了一个叫做 `s` 的空的字符串,接着我们可以向其中装载数据。通常字符串会有初始数据,因为我们希望一开始就有这个字符串。为此,可以使用 `to_string` 方法,它能用于任何实现了 `Display` trait 的类型,字符串字面值也实现了它。示例 8-12 展示了两个例子。
|
||||
这新建了一个叫做 `s` 的空的字符串,接着我们可以向其中装载数据。通常字符串会有初始数据,因为我们希望一开始就有这个字符串。为此,可以使用 `to_string` 方法,它能用于任何实现了 `Display` trait 的类型,比如字符串字面值。示例 8-12 展示了两个例子。
|
||||
|
||||
```rust
|
||||
{{#rustdoc_include ../listings/ch08-common-collections/listing-08-12/src/main.rs:here}}
|
||||
@ -163,7 +163,7 @@ let hello = "Здравствуйте";
|
||||
let answer = &hello[0];
|
||||
```
|
||||
|
||||
我们已经知道 `answer` 不是第一个字符 `З`。当使用 UTF-8 编码时,`З` 的第一个字节 `208`,第二个是 `151`,所以 `answer` 实际上应该是 `208`,不过 `208` 自身并不是一个有效的字母。返回 `208` 可不是一个请求字符串第一个字母的人所希望看到的,不过它是 Rust 在字节索引 0 位置所能提供的唯一数据。用户通常不会想要一个字节值被返回,即便这个字符串只有拉丁字母:即便 `&"hello"[0]` 是返回字节值的有效代码,它也应当返回 `104` 而不是 `h`。
|
||||
我们已经知道 `answer` 不是第一个字符 `З`。当使用 UTF-8 编码时,`З` 的第一个字节 `208`,第二个是 `151`,所以 `answer` 实际上应该是 `208`,不过 `208` 自身并不是一个有效的字母。返回 `208` 可不是一个请求字符串第一个字母的人所希望看到的,不过它是 Rust 在字节索引 0 位置所能提供的唯一数据。用户通常不会想要一个字节值被返回。即使这个字符串只有拉丁字母,如果 `&"hello"[0]` 是返回字节值的有效代码,它也会返回 `104` 而不是 `h`。
|
||||
|
||||
为了避免返回意外的值并造成不能立刻发现的 bug,Rust 根本不会编译这些代码,并在开发过程中及早杜绝了误会的发生。
|
||||
|
||||
@ -192,7 +192,7 @@ let answer = &hello[0];
|
||||
|
||||
Rust 提供了多种不同的方式来解释计算机储存的原始字符串数据,这样程序就可以选择它需要的表现方式,而无所谓是何种人类语言。
|
||||
|
||||
最后一个 Rust 不允许使用索引获取 `String` 字符的原因是,索引操作预期总是需要常数时间 (O(1))。但是对于 `String` 不可能保证这样的性能,因为 Rust 必须从开头到索引位置遍历来确定有多少有效的字符。
|
||||
最后一个 Rust 不允许使用索引获取 `String` 字符的原因是,索引操作预期总是需要常数时间(O(1))。但是对于 `String` 不可能保证这样的性能,因为 Rust 必须从开头到索引位置遍历来确定有多少有效的字符。
|
||||
|
||||
### 字符串 slice
|
||||
|
||||
@ -212,7 +212,7 @@ let s = &hello[0..4];
|
||||
{{#include ../listings/ch08-common-collections/output-only-01-not-char-boundary/output.txt}}
|
||||
```
|
||||
|
||||
你应该小心谨慎的使用这个操作,因为这么做可能会使你的程序崩溃。
|
||||
你应该小心谨慎地使用这个操作,因为这么做可能会使你的程序崩溃。
|
||||
|
||||
### 遍历字符串的方法
|
||||
|
||||
@ -254,7 +254,7 @@ for b in "Зд".bytes() {
|
||||
|
||||
### 字符串并不简单
|
||||
|
||||
总而言之,字符串还是很复杂的。不同的语言选择了不同的向程序员展示其复杂性的方式。Rust 选择了以准确的方式处理 `String` 数据作为所有 Rust 程序的默认行为,这意味着程序员们必须更多的思考如何预先处理 UTF-8 数据。这种权衡取舍相比其他语言更多的暴露出了字符串的复杂性,不过也使你在开发生命周期后期免于处理涉及非 ASCII 字符的错误。
|
||||
总而言之,字符串还是很复杂的。不同的语言选择了不同的向程序员展示其复杂性的方式。Rust 选择了以准确的方式处理 `String` 数据作为所有 Rust 程序的默认行为,这意味着程序员们必须更多的思考如何预先处理 UTF-8 数据。这种权衡取舍相比其他语言更多的暴露出了字符串的复杂性,不过也使你在开发周期后期免于处理涉及非 ASCII 字符的错误。
|
||||
|
||||
好消息是标准库提供了很多围绕 `String` 和 `&str` 构建的功能,来帮助我们正确处理这些复杂场景。请务必查看这些使用方法的文档,例如 `contains` 来搜索一个字符串,和 `replace` 将字符串的一部分替换为另一个字符串。
|
||||
|
||||
|
@ -34,7 +34,7 @@
|
||||
|
||||
<span class="caption">示例 8-21:访问哈希 map 中储存的蓝队分数</span>
|
||||
|
||||
这里,`score` 是与蓝队分数相关的值,应为 `10`。`get` 方法返回 `Option<&V>`,如果某个键在哈希 map 中没有对应的值,`get` 会返回 `None`。程序中通过调用 `copied` 方法来获取一个 `Option<i32>` 而不是 `Option<&i32>`,接着调用 `unwrap_or`,如果 `score` 没有对应键的项将 `score` 设置为零。
|
||||
这里,`score` 是与蓝队分数相关的值,应为 `10`。`get` 方法返回 `Option<&V>`,如果某个键在哈希 map 中没有对应的值,`get` 会返回 `None`。程序中通过调用 `copied` 方法来获取一个 `Option<i32>` 而不是 `Option<&i32>`,接着调用 `unwrap_or` 在 `score` 中没有该键所对应的项时将其设置为零。
|
||||
|
||||
可以使用与 vector 类似的方式来遍历哈希 map 中的每一个键值对,也就是 `for` 循环:
|
||||
|
||||
@ -107,7 +107,7 @@ Blue: 10
|
||||
|
||||
<span class="caption">示例 8-25:通过哈希 map 储存单词和计数来统计出现次数</span>
|
||||
|
||||
这会打印出 `{"world": 2, "hello": 1, "wonderful": 1}`。你可能会发现相同的键值对以不同的顺序打印:回忆以下[“访问哈希 map 中的值”][access]部分中遍历哈希 map 会以任意顺序进行。
|
||||
这会打印出 `{"world": 2, "hello": 1, "wonderful": 1}`。你可能会看到相同的键值对以不同的顺序打印:回忆一下[“访问哈希 map 中的值”][access]部分中遍历哈希 map 会以任意顺序进行。
|
||||
|
||||
`split_whitespace` 方法返回一个由空格分隔 `text` 值子 slice 的迭代器。`or_insert` 方法返回这个键的值的一个可变引用(`&mut V`)。这里我们将这个可变引用储存在 `count` 变量中,所以为了赋值必须首先使用星号(`*`)解引用 `count`。这个可变引用在 `for` 循环的结尾离开作用域,这样所有这些改变都是安全的并符合借用规则。
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user