Refining Ch03.

This commit is contained in:
rust-lang.xfoss.com 2023-12-08 15:54:06 +08:00
parent f413255aae
commit 33161694d1
3 changed files with 54 additions and 19 deletions

View File

@ -0,0 +1,8 @@
[package]
name = "tuple_demo"
version = "0.1.0"
edition = "2021"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]

View File

@ -0,0 +1,5 @@
fn main() {
let a: [i32; 5] = [-1, 0, 1, 2, 3];
println! ("a[0]: {a.0}");
}

View File

@ -209,21 +209,30 @@ fn main() {
let z: char = ''; // 带有显式的类型注解
let heart_eyed_cat = '😻';
println! ("c 为 {c}, z 为 {z}, 爱心猫: {heart_eyed_ca");
println! ("c 为 {c}, z 为 {z}, 爱心猫: {heart_eyed_cat}");
}
```
请注意,相比使用双引号来给字符串字面值进行值的指定,这里是以单引号来对这些 `char` 的字面值进行指定的。Rust 的 `char` 类型,有着四个字节的大小,而表示了 Unicode 的标量值,这就意味着他可以表示比仅仅 ASCII 要多得多的符号。像是重音字母accented letters中文、日语、韩语等等emoji 符号;以及那些零宽度空格等等,在 Rust 中都是有效的 `char` 取值。Unicode 标量值的范围,是从 `U+0000``U+D7FF`,及 `U+E000``U+10FFFF`包含边界值。不过“字符character” 并非 Unicode 中的概念,因此对 “字符” 为何物的主观认识,可能与 Rust 中 `char` 的本质有所差别。在第 8 章中的 [用字符串存储 UTF-8 编码的文本](Ch08_Strings.md#使用-string-存储-utf-8-编码的文本) 小节,将对此话题进行讨论。
请注意,我们使用单引号指定 `char` 字面值而字符串字面值则使用双引号。Rust 的 `char` 类型大小为 4 个字节,表示某个 Unicode 的标量值a Unicode Scalar Value这意味着他可以表示的字符不仅仅是 ASCII。在 Rust 中,重音字母、中日韩文字、表情符号和零宽度的空格等,都是有效的 `char` 值。Unicode 标量值的范围为 `U+0000``U+D7FF``U+E000``U+10FFFF`(含)。不过,所谓 “字符”,在 Unicode 中并不是个真正的概念,因此咱们对 “字符” 的直觉,可能与 Rust 中的字符不一致。我们将在第 8 章,[“使用 `String` 存储 UTF-8 编码的文本”](../common_collections/strings.md) 小节中,详细讨论这个问题。
## 复合类型
*复合类型compound types* 可将多个值组合成一个类型。Rust 有着两个原生的复合类型元组与数组tuples and arrays
**Compound Types**
*复合类型compound types*可以将多个值编为一种类型。Rust 有两种原始的复合类型:元组和数组。
### 元组类型
元组是将数个不同类型的值,组合成一个复合类型的一般方式。元组是固定长度的:一旦被声明出来,他们的大小就无法扩大或缩小了。
**The Tuple Type**
元组是将不同类型的多个值,组合在一起成为一个复合类型的通用方法。元组有固定的长度:一旦声明了出来,其大小就不能增大或缩小。
我们通过在括号内写入一个以逗号分隔的值列表,来创建一个元组。元组中的每个位置都有一个类型,元组中不同值的类型不必相同。在下面这个示例中,我们添加了可选的类型注解:
通过编写放在圆括号里面的、逗号分隔的值清单,来创建元组。元组中每个位置都有着一种类型,同时元组中不同值的类型不必一致。下面的示例中,加上了那些可选的类型注解:
文件名:`src/main.rs`
@ -233,23 +242,27 @@ fn main() {
}
```
由于元组被当作是单一复合元素,因此这里的变量 `tup` 绑定到了那整个的元组。要从元组获取到其单个值,就要使用模式匹配,来对元组值进行解构,就像下面这样:
该变量 `tup` 会绑定到整个元组,因为元组被视为单一的复合元素。而要从某个元组中获取单个值,我们可以使用模式匹配,来解构某个元组值,就像这样:
文件名:`src/main.rs`
```rust
fn main() {
let tup = (500, 6.4, 1, "元组的最后一个元素");
let tup = (500, 6.4, 1);
let (x, y, z, a) = tup;
let (x, y, z) = tup;
println! ("a 的值为:{}", a);
println! ("y 的值为:{y}");
}
```
这个程序首先创建了一个元组,并将其绑定到了变量 `tup`。随后以 `let` 关键字,使用了一个模式来取得 `tup`,并将其转换为四个独立变量,分别为 `x`、`y`、`z` 与 `a`。由于该操作将单个的元素,打散为了四个部分,因此称之为 *解构destructuring*。最后,程序打印出了 `a` 的值,即为 `元组的最后一个元素`
还可以通过使用句点(`.`)后带上想要访问值的索引,还可直接对某个元组元素进行访问。比如:
这个程序首先创建了一个元组,并将其绑定到变量 `tup`。然后,程序使用一个带有 `let` 的模式,来取 `tup`,并将其变成三个独立的变量 `x`、`y` 和 `z`。这叫做 *解构destructuring*,因为他将单个元组,分解为了三个部分。最后,该程序打印出 `y` 的值,即 `6.4`
我们还可以通过使用后跟要访问值索引的句点(`.`),直接访问某个元组元素。例如:
文件名:`src/main.rs`
@ -263,20 +276,25 @@ fn main() {
let one = x.2;
println! ("x.0 {}, x.1{}, x.2{}", five_hundred, six_point_four, one);
println! ("x.0{five_hundred}, x.1{six_point_four}, x.2{one}");
}
```
此程序创建了元组 `x`,并随后通过使用各个元素的索引,而构造了他们的新变量。与绝大多数编程语言一样,元组的首个索引为 `0`
没有任何值的元组,`()`,是种仅有一个值的特殊类型,同样写作 `()`。该类型叫做 *单元类型unit type*,同时这个值叫做 *单元值unit value*。那些不返回任何值的表达式,就会显式地返回这个单元值。
此程序创建了一个元组 `x`,然后使用其各自索引,访问了元组中的每个元素。与大多数编程语言一样,元组中的第一个索引为 0。
没有任何值的元组,有一个特殊的名称,*单元值unit*。这个值及其对应的类型,都被写成 `()`,并表示某个空值,或空返回类型。如果表达式不返回任何别的值,则会隐式返回这个单元值。
### 数组类型
*数组array* 是拥有多个值集合的另一种方式。不同于元组数组中的每个元素都必须是同一类型。与其他一些语言中的数组不同Rust 中的数组是定长的。
**The Array Type**
另一种拥有多个值集合的方法,是使用 *数组array*。与元组不同数组的每个元素都必须有着同样类型。与其他一些语言中的数组不同Rust 中的数组有着固定长度。
我们将数组中的值,写作方括号内以逗号分隔的列表:
以方括号(`[]`)中逗号分隔的方式,来编写数组中个那些值:
文件:`src/main.rs`
@ -286,21 +304,25 @@ fn main() {
}
```
在希望数据分配在栈而不是堆(在 [第 4 章](Ch04_Understanding_Ownership.md#何谓所有权) 将进一步讨论栈与堆)上时,或希望确保一直有着固定数目的元素时,数组就派上用场了。然而,数组不如矢量类型灵活。矢量是标准库所提供的,一种类似的集合类型,其大小 *可以* 变大或缩小。在不确定要使用数组,还是要使用矢量类型时,那多半就应该使用矢量了。[第 8 章](Ch08_Common_Collections.md#使用矢量类型对值清单进行存储) 对矢量类型进行了更详细的讨论。
当咱们希望咱们的数据,分配在栈上而不是堆上时(我们将在 [第 4 章](ownership/about_ownership.md) 详细讨论栈和堆),或者当咱们希望确保始终有着固定数量元素时,数组就非常有用。不过,数组不如矢量类型灵活。所谓 *矢量vector*,是标准库提供的一种类似的集合类型,其大小 *可以* 增大或缩小。如果咱们不确定是使用数组还是矢量,那么很可能应该使用矢量。[第 8 章](../common_collections/vectors.md) 会详细讨论矢量。
不过,当我们清楚元素数量今后不会需要改变时,数组会更有用。例如,如果咱们要在程序中使用月份的那些名字时,咱们就可能会使用数组而不是矢量,因为咱们知道他将始终包含 12 个元素:
尽管如此,在了解了元素数目无需变化时,数组将更为有用。比如,在程序中正使用着各个月份名字时,由于是知道那将总是包含 12 个元素,因此就要使用数组而非矢量类型:
```rust
let months = ["January", "February", "March", "April", "May", "June", "July",
"August", "September", "October", "November", "December"];
```
数组类型的编写,是以方括弧(`[]`)括起来的,各个元素的类型,一个分号(`;`),和数组中元素个数的形式,像下面这样:
咱们可以使用带有每个元素的类型、分号以及数组中元素的数量的方括号,来写出某个数组的类型,如下所示:
```rust
let a: [i32, 5] = [-1, 0, 1, 2, 3];
```
这里,`i32`就是各个元素的类型。在分号之后,数字 `5` 表示该数组包含五个元素。
还可以通过在方括弧(`[]`)中,先指定初始值,接着一个分号(`;`),及随后数组长度的方式,初始化出一个包含各个元素为同一个值的数组,如下所示: