|
|
|
@ -4,9 +4,9 @@
|
|
|
|
|
> <br>
|
|
|
|
|
> commit f4bce88a0f4c09aaf0c996021729c6d42907bc2a
|
|
|
|
|
|
|
|
|
|
在 Rust 中,任何值都属于一种明确的 **类型**(*type*),这告诉了 Rust 它被指定了何种数据,以便明确其处理方式。我们将分两部分探讨一些内建类型:标量(scalar)和复合(compound)。
|
|
|
|
|
在 Rust 中,任何值都属于一种明确的 **类型**(*type*),这告诉了 Rust 它被指定为何种数据,以便明确其处理方式。我们将分两部分探讨一些内建类型:标量(scalar)和复合(compound)。
|
|
|
|
|
|
|
|
|
|
Rust 是 **静态类型**(*statically typed*)语言,也就是说在编译时就必须知道所有变量的类型,这一认知将贯穿整个章节,请在头脑中明确。通过值的形式及其使用方式,编译器通常可以推断出我们想要用的类型。多种类型均有可能时,比如第二章中使用 `parse` 将 `String` 转换为数字时,必须增加类型注解,像这样:
|
|
|
|
|
Rust 是 **静态类型**(*statically typed*)语言,也就是说在编译时就必须知道所有变量的类型,这一点将贯穿整个章节。通过值的形式及其使用方式,编译器通常可以推断出我们想要用的类型。多种类型均有可能时,比如第二章中使用 `parse` 将 `String` 转换为数字时,必须增加类型注解,像这样:
|
|
|
|
|
|
|
|
|
|
```rust
|
|
|
|
|
let guess: u32 = "42".parse().expect("Not a number!");
|
|
|
|
@ -28,7 +28,7 @@ error[E0282]: unable to infer enough type information about `_`
|
|
|
|
|
|
|
|
|
|
### 标量类型
|
|
|
|
|
|
|
|
|
|
**标量**(*scalar*)类型代表一个单独的值。Rust 有四种基本的标量类型:整型、浮点型、布尔类型和字符类型。你可能在其他语言中见过他们,不过让我们深入了解他们在 Rust 中时如何工作的。
|
|
|
|
|
**标量**(*scalar*)类型代表一个单独的值。Rust 有四种基本的标量类型:整型、浮点型、布尔类型和字符类型。你可能在其他语言中见过它们,不过让我们深入了解它们在 Rust 中时如何工作的。
|
|
|
|
|
|
|
|
|
|
#### 整型
|
|
|
|
|
|
|
|
|
@ -48,9 +48,9 @@ error[E0282]: unable to infer enough type information about `_`
|
|
|
|
|
|
|
|
|
|
每一个有符号的变体可以储存包含从 -(2<sup>n - 1</sup>) 到 2<sup>n - 1</sup> - 1 在内的数字,这里 `n` 是变体使用的位数。所以 `i8` 可以储存从 -(2<sup>7</sup>) 到 2<sup>7</sup> - 1 在内的数字,也就是从 -128 到 127。无符号的变体可以储存从 0 到 2<sup>n</sup> - 1 的数字,所以 `u8` 可以储存从 0 到 2<sup>8</sup> - 1 的数字,也就是从 0 到 255。
|
|
|
|
|
|
|
|
|
|
另外,`isize` 和 `usize` 类型依赖运行程序的计算机架构:64 位架构上他们是 64 位的, 32 位架构上他们是 32 位的。
|
|
|
|
|
另外,`isize` 和 `usize` 类型依赖运行程序的计算机架构:64 位架构上它们是 64 位的, 32 位架构上它们是 32 位的。
|
|
|
|
|
|
|
|
|
|
可以使用表格 3-2 中的任何一种形式编写数字字面值。注意除字节以外的其它字面值允许使用类型后缀,例如 `57u8`,同时也允许使用 `_` 做为分隔符以方便读数,例如`1_000`。
|
|
|
|
|
可以使用表格 3-2 中的任何一种形式编写数字字面值。注意除 byte 以外的其它字面值允许使用类型后缀,例如 `57u8`,同时也允许使用 `_` 做为分隔符以方便读数,例如`1_000`。
|
|
|
|
|
|
|
|
|
|
<span class="caption">表格 3-2: Rust 中的整型字面值</span>
|
|
|
|
|
|
|
|
|
@ -84,7 +84,7 @@ fn main() {
|
|
|
|
|
|
|
|
|
|
#### 数字运算符
|
|
|
|
|
|
|
|
|
|
Rust 支持所有数字类型常见的基本数学运算操作:加法、减法、乘法、除法以及余数。如下代码展示了如何使用一个 `let` 语句来使用他们:
|
|
|
|
|
Rust 支持所有数字类型常见的基本数学运算操作:加法、减法、乘法、除法以及取余。下面的代码展示了如何在一个 `let` 语句中使用它们:
|
|
|
|
|
|
|
|
|
|
<span class="filename">文件名: src/main.rs</span>
|
|
|
|
|
|
|
|
|
@ -107,7 +107,7 @@ fn main() {
|
|
|
|
|
}
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
这些语句中的每个表达式使用了一个数学运算符并计算出了一个值,他们绑定到了一个变量。附录 B 包含了一个 Rust 提供的所有运算符的列表。
|
|
|
|
|
这些语句中的每个表达式使用了一个数学运算符并计算出了一个值,它们绑定到了一个变量。附录 B 包含了一个 Rust 提供的所有运算符的列表。
|
|
|
|
|
|
|
|
|
|
#### 布尔型
|
|
|
|
|
|
|
|
|
@ -123,7 +123,7 @@ fn main() {
|
|
|
|
|
}
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
使用布尔值的主要场景是条件表达式,例如 `if` 表达式。在 “控制流”(“Control Flow”)部分将讲到`if`表达式在 Rust 中如何工作。
|
|
|
|
|
使用布尔值的主要场景是条件表达式,例如 `if` 表达式。在 “控制流”(“Control Flow”)部分将讲到 `if` 表达式在 Rust 中如何工作。
|
|
|
|
|
|
|
|
|
|
#### 字符类型
|
|
|
|
|
|
|
|
|
@ -139,7 +139,7 @@ fn main() {
|
|
|
|
|
}
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
Rust 的 `char` 类型代表了一个 Unicode 标量值(Unicode Scalar Value),这意味着它可以比 ASCII 表示更多内容。拼音字母(Accented letters),中文/日文/汉语等象形文字,emoji(絵文字)以及零长度的空白字符对于 Rust `char`类型都是有效的。Unicode 标量值包含从 `U+0000` 到 `U+D7FF` 和 `U+E000` 到 `U+10FFFF` 之间的值。不过,“字符” 并不是一个 Unicode 中的概念,所以人直觉上的 “字符” 可能与 Rust 中的 `char` 并不符合。第八章的 “字符串” 部分将详细讨论这个主题。
|
|
|
|
|
Rust 的 `char` 类型代表了一个 Unicode 标量值(Unicode Scalar Value),这意味着它可以比 ASCII 表示更多内容。拼音字母(Accented letters),中文/日文/韩文等象形文字,emoji(絵文字)以及零长度的空白字符对于 Rust `char` 类型都是有效的。Unicode 标量值包含从 `U+0000` 到 `U+D7FF` 和 `U+E000` 到 `U+10FFFF` 之间的值。不过,“字符” 并不是一个 Unicode 中的概念,所以人直觉上的 “字符” 可能与 Rust 中的 `char` 并不符合。第八章的 “字符串” 部分将详细讨论这个主题。
|
|
|
|
|
|
|
|
|
|
### 复合类型
|
|
|
|
|
|
|
|
|
@ -173,9 +173,9 @@ fn main() {
|
|
|
|
|
}
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
程序首先创建了一个元组并绑定到 `tup` 变量上。接着使用了 `let` 和一个模式将 `tup` 分成了三个不同的变量,`x`、`y` 和 `z`。这叫做 *解构*(*destructuring*),因为它将一个元组拆成了三个部分。最后,程序打印出了 `y` 的值,也就是 `6.4`。
|
|
|
|
|
程序首先创建了一个元组并绑定到 `tup` 变量上。接着使用了 `let` 和一个模式将 `tup` 分成了三个不同的变量,`x`、`y` 和 `z`。这叫做 **解构**(*destructuring*),因为它将一个元组拆成了三个部分。最后,程序打印出了 `y` 的值,也就是 `6.4`。
|
|
|
|
|
|
|
|
|
|
除了使用模式匹配解构之外,也可以使用点号(`.`)后跟值的索引来直接访问他们。例如:
|
|
|
|
|
除了使用模式匹配解构之外,也可以使用点号(`.`)后跟值的索引来直接访问它们。例如:
|
|
|
|
|
|
|
|
|
|
<span class="filename">文件名: src/main.rs</span>
|
|
|
|
|
|
|
|
|
@ -195,7 +195,7 @@ fn main() {
|
|
|
|
|
|
|
|
|
|
#### 数组
|
|
|
|
|
|
|
|
|
|
另一个获取一个多个值集合的方式是 **数组**(*array*)。与元组不同,数组中的每个元素的类型必须相同。Rust 中的数组与一些其他语言中的数组不同,因为 Rust 中的数组是固定长度的:一旦声明,他们的长度不能增长或缩小。
|
|
|
|
|
另一个获取一个多个值集合的方式是 **数组**(*array*)。与元组不同,数组中的每个元素的类型必须相同。Rust 中的数组与一些其他语言中的数组不同,因为 Rust 中的数组是固定长度的:一旦声明,它们的长度不能增长或缩小。
|
|
|
|
|
|
|
|
|
|
Rust 中数组的值位于中括号中的逗号分隔的列表中:
|
|
|
|
|
|
|
|
|
@ -207,9 +207,9 @@ fn main() {
|
|
|
|
|
}
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
数组需要在栈(stack)而不是在堆(heap)上为数据分配空间时(第四章将讨论栈与堆的更多内容),或者是想要确保总是有固定数量的元素时十分有用。虽然它并不如 vector 类型那么灵活。vector 类型是标准库提供的一个 **允许** 增长和缩小长度的类似数组的集合类型。当不确定是应该使用数组还是 vector 的时候,你可能应该使用 vector:第八章会详细讨论 vector。
|
|
|
|
|
当你想要在栈(stack)而不是在堆(heap)上为数据分配空间(第四章将讨论栈与堆的更多内容),或者是想要确保总是有固定数量的元素时,数组非常有用,虽然它并不如 vector 类型那么灵活。vector 类型是标准库提供的一个 **允许** 增长和缩小长度的类似数组的集合类型。当不确定是应该使用数组还是 vector 的时候,你可能应该使用 vector。第八章会详细讨论 vector。
|
|
|
|
|
|
|
|
|
|
一个你可能想要使用数组而不是 vector 的例子是当程序需要知道一年中月份的名字时。程序不大可能会去增加或减少月份,这时你可以使用数组因为我们知道它总是含有 12 个元素:
|
|
|
|
|
一个你可能想要使用数组而不是 vector 的例子是,当程序需要知道一年中月份的名字时,程序不大可能会去增加或减少月份。这时你可以使用数组,因为我们知道它总是含有 12 个元素:
|
|
|
|
|
|
|
|
|
|
```rust
|
|
|
|
|
let months = ["January", "February", "March", "April", "May", "June", "July",
|
|
|
|
@ -235,7 +235,7 @@ fn main() {
|
|
|
|
|
|
|
|
|
|
##### 无效的数组元素访问
|
|
|
|
|
|
|
|
|
|
如果我们访问数组结尾之后的元素会发生什么呢?比如我们将上面的例子改为如下:
|
|
|
|
|
如果我们访问数组结尾之后的元素会发生什么呢?比如我们将上面的例子改成下面这样:
|
|
|
|
|
|
|
|
|
|
<span class="filename">文件名: src/main.rs</span>
|
|
|
|
|
|
|
|
|
|