2023-05-19 08:18:48 +08:00
|
|
|
|
[#]: subject: "Rust Basics Series #4: Arrays and Tuples in Rust"
|
|
|
|
|
[#]: via: "https://itsfoss.com/rust-arrays-tuples/"
|
|
|
|
|
[#]: author: "Pratham Patel https://itsfoss.com/author/pratham/"
|
|
|
|
|
[#]: collector: "lkxed"
|
|
|
|
|
[#]: translator: "Cubik65536"
|
2023-05-23 16:58:39 +08:00
|
|
|
|
[#]: reviewer: "wxy"
|
|
|
|
|
[#]: publisher: "wxy"
|
|
|
|
|
[#]: url: "https://linux.cn/article-15837-1.html"
|
2023-05-19 08:18:48 +08:00
|
|
|
|
|
|
|
|
|
Rust 基础系列 #4: Rust 中的数组和元组
|
|
|
|
|
======
|
|
|
|
|
|
2023-05-23 16:58:39 +08:00
|
|
|
|
![][0]
|
|
|
|
|
|
|
|
|
|
> 在 Rust 系列的第四篇中,学习复合数据类型、数组和元组。
|
|
|
|
|
|
|
|
|
|
在上一篇文章中,你学习到了 Rust 中的 [标量数据类型][1]。它们是整型、浮点数、字符和布尔值。
|
2023-05-19 08:18:48 +08:00
|
|
|
|
|
|
|
|
|
在本文中,我们将会看看 Rust 编程语言中的复合数据类型。
|
|
|
|
|
|
|
|
|
|
### Rust 中的复合数据类型是什么?
|
|
|
|
|
|
|
|
|
|
复合数据类型可以在一个变量中存储多个值。这些值可以是相同的标量数据类型,也可以是不同的标量数据类型。
|
|
|
|
|
|
|
|
|
|
Rust 编程语言中有两种这样的数据类型:
|
|
|
|
|
|
2023-05-23 16:58:39 +08:00
|
|
|
|
- <ruby>数组<rt>Array</rt></ruby>:存储相同类型的多个值。
|
|
|
|
|
- <ruby>元组<rt>Tuple</rt></ruby>:存储多个值,可以是相同的类型,也可以是不同的类型。
|
2023-05-19 08:18:48 +08:00
|
|
|
|
|
|
|
|
|
让我们了解一下它们吧!
|
|
|
|
|
|
|
|
|
|
### Rust 中的数组
|
|
|
|
|
|
|
|
|
|
Rust 编程语言中的数组具有以下特性:
|
|
|
|
|
|
|
|
|
|
- 每一个元素都必须是相同的类型
|
2023-05-23 16:58:39 +08:00
|
|
|
|
- 数组有一个固定的长度
|
2023-05-19 08:18:48 +08:00
|
|
|
|
- 数组存储在堆栈中,即其中存储的数据可以被 _迅速_ 访问
|
|
|
|
|
|
|
|
|
|
创建数组的语法如下:
|
|
|
|
|
|
|
|
|
|
```
|
|
|
|
|
// 无类型声明
|
|
|
|
|
let variable_name = [element1, element2, ..., elementn];
|
|
|
|
|
|
|
|
|
|
// 有类型声明
|
|
|
|
|
let variable_name: [data_type; array_length] = [element1, element2, ..., elementn];
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
数组中的元素是在方括号中声明的。要访问数组的元素,需要在方括号中指定要访问的索引。
|
|
|
|
|
|
|
|
|
|
来让我们看一个例子来更好地理解这个。
|
|
|
|
|
|
|
|
|
|
```
|
|
|
|
|
fn main() {
|
|
|
|
|
// 无类型声明
|
|
|
|
|
let greeting = ['H', 'e', 'l', 'l', 'o', ' ', 'w', 'o', 'r', 'l', 'd', '!'];
|
|
|
|
|
|
|
|
|
|
// 有类型声明
|
|
|
|
|
let pi: [i32; 10] = [1, 4, 1, 5, 9, 2, 6, 5, 3, 5];
|
|
|
|
|
|
|
|
|
|
for character in greeting {
|
|
|
|
|
print!("{}", character);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
println!("\nPi: 3.1{}{}{}{}", pi[0], pi[1], pi[2], pi[3]);
|
|
|
|
|
}
|
|
|
|
|
```
|
|
|
|
|
|
2023-05-23 16:58:39 +08:00
|
|
|
|
这里,我定义了一个字符数组和另一个存储 `i32` 类型的值的数组。`greeting` 数组以单独字符的形式存储了字符串 `"Hello world!"` 的字符。`pi` 数组以单独数字的形式存储了圆周率小数点后的前 10 位数字。
|
2023-05-19 08:18:48 +08:00
|
|
|
|
|
|
|
|
|
然后,我使用 `for` 循环打印了 `greeting` 数组的每个字符。(我很快就会讲到循环。)然后,我打印了 `pi` 数组的前 4 个值。
|
|
|
|
|
|
|
|
|
|
```
|
|
|
|
|
Hello world!
|
|
|
|
|
Pi: 3.11415
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
如果你想创建一个数组,其中每个元素都是 _y_,并且出现 _x_ 次,你可以使用以下快捷方式在 Rust 中实现:
|
|
|
|
|
|
|
|
|
|
```
|
|
|
|
|
let variable_name = [y; x];
|
|
|
|
|
```
|
|
|
|
|
|
2023-05-23 16:58:39 +08:00
|
|
|
|
来看一个演示……
|
2023-05-19 08:18:48 +08:00
|
|
|
|
|
|
|
|
|
```
|
|
|
|
|
fn main() {
|
|
|
|
|
let a = [10; 5];
|
|
|
|
|
|
|
|
|
|
for i in a {
|
|
|
|
|
print!("{i} ");
|
|
|
|
|
}
|
|
|
|
|
println!("");
|
|
|
|
|
}
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
我创建了一个变量 `a`,它的长度为 5。数组中的每个元素都是 '10'。我通过使用 `for` 循环打印数组的每个元素来验证这一点。
|
|
|
|
|
|
|
|
|
|
它的输出如下:
|
|
|
|
|
|
|
|
|
|
```
|
|
|
|
|
10 10 10 10 10
|
|
|
|
|
```
|
|
|
|
|
|
2023-05-23 16:58:39 +08:00
|
|
|
|
> 🤸 作为练习,尝试创建一个长度为 _x_ 的数组,然后尝试访问数组的第 _x+1_ 个元素。看看会发生什么。
|
2023-05-19 08:18:48 +08:00
|
|
|
|
|
|
|
|
|
### Rust 中的元组
|
|
|
|
|
|
|
|
|
|
Rust 中的元组具有以下特性:
|
|
|
|
|
|
|
|
|
|
- 就像数组一样,元组的长度是固定的
|
|
|
|
|
- 元素可以是相同的/不同的标量数据类型
|
|
|
|
|
- 元组存储在堆栈中,所以访问速度更快
|
|
|
|
|
|
|
|
|
|
创建元组的语法如下:
|
|
|
|
|
|
|
|
|
|
```
|
|
|
|
|
// 无类型声明
|
|
|
|
|
let variable_name = (element1, element2, ..., element3);
|
|
|
|
|
|
|
|
|
|
// 有类型声明
|
|
|
|
|
let variable_name: (data_type, ..., data_type) = (element1, element2, ..., element3);
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
元组的元素写在圆括号中。要访问元素,使用点运算符,后跟该元素的索引。
|
|
|
|
|
|
|
|
|
|
```
|
|
|
|
|
fn main() {
|
|
|
|
|
let a = (38, 923.329, true);
|
|
|
|
|
let b: (char, i32, f64, bool) = ('r', 43, 3.14, false);
|
|
|
|
|
|
|
|
|
|
println!("a.0: {}, a.1: {}, a.2: {}", a.0, a.1, a.2);
|
|
|
|
|
println!("b.0: {}, b.1: {}, b.2: {}, b.3: {}", b.0, b.1, b.2, b.3);
|
|
|
|
|
|
|
|
|
|
// 元组解构
|
|
|
|
|
let pixel = (50, 0, 200);
|
|
|
|
|
let (red, green, blue) = pixel;
|
|
|
|
|
println!("red: {}, green: {}, blue: {}", red, green, blue);
|
|
|
|
|
}
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
在上面的代码中,我在第 2 行和第 3 行声明了两个元组。它们只包含我当时想到的随机值。但是仔细看,两个元组中每个元素的数据类型都不同。然后,在第 5 行和第 6 行,我打印了两个元组的每个元素。
|
|
|
|
|
|
2023-05-23 16:58:39 +08:00
|
|
|
|
在第 9 行,我声明了一个名为 `pixel` 的元组,它有 3 个元素。每个元素都是组成像素的颜色红色、绿色和蓝色的亮度值。这个范围是从 0 到 255。所以,理想情况下,我会声明类型为 `(u8, u8, u8)`,但是在学习代码时不需要这样优化 ; )
|
2023-05-19 08:18:48 +08:00
|
|
|
|
|
|
|
|
|
然后,在第 10 行,我“解构”了 `pixel` 元组的每个值,并将其存储在单独的变量 `red`、`green` 和 `blue` 中。然后,我打印了 `red`、`green` 和 `blue` 变量的值,而不是 `pixel` 元组的值。
|
|
|
|
|
|
2023-05-23 16:58:39 +08:00
|
|
|
|
让我们看看输出……
|
2023-05-19 08:18:48 +08:00
|
|
|
|
|
|
|
|
|
```
|
|
|
|
|
a.0: 38, a.1: 923.329, a.2: true
|
|
|
|
|
b.0: r, b.1: 43, b.2: 3.14, b.3: false
|
|
|
|
|
red: 50, green: 0, blue: 200
|
|
|
|
|
```
|
|
|
|
|
|
2023-05-23 16:58:39 +08:00
|
|
|
|
看起来不错 : )
|
2023-05-19 08:18:48 +08:00
|
|
|
|
|
|
|
|
|
### 额外内容:切片
|
|
|
|
|
|
2023-05-23 16:58:39 +08:00
|
|
|
|
准确的来说,<ruby>切片<rt>Slice</rt></ruby> 不是 Rust 中的复合数据类型。相反,切片是现有复合数据类型的 “切片”。
|
2023-05-19 08:18:48 +08:00
|
|
|
|
|
|
|
|
|
一个切片由三个元素组成:
|
|
|
|
|
|
|
|
|
|
- 一个初始索引
|
2023-05-23 16:58:39 +08:00
|
|
|
|
- 切片运算符(`..` 或 `..=`)
|
2023-05-19 08:18:48 +08:00
|
|
|
|
- 一个结束索引
|
|
|
|
|
|
2023-05-23 16:58:39 +08:00
|
|
|
|
接下来是数组切片的一个示例:
|
2023-05-19 08:18:48 +08:00
|
|
|
|
|
|
|
|
|
```
|
|
|
|
|
fn main() {
|
|
|
|
|
let my_array = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9];
|
|
|
|
|
let my_slice = &my_array[0..4];
|
|
|
|
|
|
|
|
|
|
for element in my_slice {
|
|
|
|
|
println!("{element}");
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
就像 C 和 C++ 一样,`&` 用于存储变量的引用(而不是原始指针)。所以 `&my_array` 意味着对变量 `my_array` 的引用。
|
|
|
|
|
|
|
|
|
|
然后,来看看切片。切片由 `[0..4]` 表示。这里,`0` 是切片开始的索引。而 `4` 是切片结束的索引。这里的 4 是一个非包含索引。
|
|
|
|
|
|
|
|
|
|
这是程序输出,以更好地理解正在发生的事情:
|
|
|
|
|
|
|
|
|
|
```
|
|
|
|
|
0
|
|
|
|
|
1
|
|
|
|
|
2
|
|
|
|
|
3
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
如果你想要一个 _包含_ 范围,你可以使用 `..=` 作为包含范围的切片运算符。
|
|
|
|
|
|
|
|
|
|
```
|
|
|
|
|
fn main() {
|
|
|
|
|
let my_array = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9];
|
|
|
|
|
let my_slice = &my_array[0..=4];
|
|
|
|
|
|
|
|
|
|
for element in my_slice {
|
|
|
|
|
println!("{element}");
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
现在,这个范围是从第 0 个元素到第 4 个元素,下面是输出来证明这一点:
|
|
|
|
|
|
|
|
|
|
```
|
|
|
|
|
0
|
|
|
|
|
1
|
|
|
|
|
2
|
|
|
|
|
3
|
|
|
|
|
4
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
### 总结
|
|
|
|
|
|
|
|
|
|
本文讲到了 Rust 编程语言中的复合数据类型。你学习了如何声明和访问存储在数组和元组类型中的值。此外,你还了解了切片“类型”,以及如何解构元组。
|
|
|
|
|
|
|
|
|
|
在下一章中,你将学习如何在 Rust 程序中使用函数。敬请关注。
|
|
|
|
|
|
2023-05-23 16:58:39 +08:00
|
|
|
|
*(题图:MJ/22a0d143-2216-439f-8e1d-abd94cdfdbd0)*
|
|
|
|
|
|
2023-05-19 08:18:48 +08:00
|
|
|
|
--------------------------------------------------------------------------------
|
|
|
|
|
|
|
|
|
|
via: https://itsfoss.com/rust-arrays-tuples/
|
|
|
|
|
|
|
|
|
|
作者:[Pratham Patel][a]
|
|
|
|
|
选题:[lkxed][b]
|
|
|
|
|
译者:[Cubik65536](https://github.com/Cubik65536)
|
2023-05-23 16:58:39 +08:00
|
|
|
|
校对:[wxy](https://github.com/wxy)
|
2023-05-19 08:18:48 +08:00
|
|
|
|
|
|
|
|
|
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
|
|
|
|
|
|
|
|
|
[a]: https://itsfoss.com/author/pratham/
|
|
|
|
|
[b]: https://github.com/lkxed/
|
2023-05-23 16:58:39 +08:00
|
|
|
|
[1]: https://linux.cn/article-15811-1.html
|
|
|
|
|
[0]: https://img.linux.net.cn/data/attachment/album/202305/23/165645ljp41i87p7xcpx1z.jpg
|