Update enum.md

pull/174/head
Jesse 3 years ago committed by GitHub
parent 7535ea782b
commit 6df9b08d74
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -87,7 +87,7 @@ fn main() {
}
```
直接将数据信息关联到枚举成员上,省去近一半的代码,这种实现是不是更漂亮
直接将数据信息关联到枚举成员上,省去近一半的代码,这种实现是不是更优雅
不仅如此,同一个枚举类型下的不同成员还能持有不同的数据类型,例如让某些花色打印`1-13`的字样,另外的花色打印上`A-K`的字样:
```rust
@ -159,7 +159,7 @@ struct WriteMessage(String); // 元组结构体
struct ChangeColorMessage(i32, i32, i32); // 元组结构体
```
由于每个结构体都有自己的类型,采用结构体的方式定义这些消息相当于声明了四个结构体,如果一个函数只允许传入一个类型的变量,这样显然是不合适的,例如某个函数它的功能是接受消息并进行发送,那么用枚举的方式只需要一种枚举类型就可以接收不同的消息但是如果用结构体该函数需要接受4个不同的结构体作为参数这样就复杂了很多。
由于每个结构体都有自己的类型,采用结构体的方式定义这些消息相当于声明了四个结构体,如果一个函数只允许传入一个类型的变量,这样显然是无法实现的,例如某个函数它的功能是接受消息并进行发送,如果使用枚举的方式,只需要一种枚举类型就可以接收不同的消息,但是如果使用结构体,那么该函数需要接受4个不同的结构体作为参数这样就复杂了很多。
而且从代码规范角度来看,枚举的实现更简洁,代码内聚性更强,不像结构体的实现,分散在各个地方。
@ -209,7 +209,7 @@ enum Option<T> {
其中`T`是泛型参数,`Some(T)`表示该枚举成员的数据类型是`T`, 换句话说,`Some`可以包含任何类型的数据。
`Option<T>` 枚举是如此有用以至于它甚至被包含在了`prelude`(属于Rust标准库Rust会将最常用的类型、函数等提前引入进来,避免我们再手动引入)之中,你不需要将其显式引入作用域。另外,它的成员也是如此,无需使用`Option::`前缀就可直接使用`Some` 和 `None`。总之,不能因为`Some(T)`和`None`中没有`Option::`的身影,就否认它们是`Option`下的卧龙凤雏。
`Option<T>` 枚举是如此有用以至于它甚至被包含在了`prelude`(prelude属于Rust标准库Rust会将最常用的类型、函数等提前引入其中,避免我们再手动引入)之中,你不需要将其显式引入作用域。另外,它的成员`Some` 和 `None`也是如此,无需使用`Option::`前缀就可直接使用`Some` 和 `None`。总之,不能因为`Some(T)`和`None`中没有`Option::`的身影,就否认它们是`Option`下的卧龙凤雏。
再来看以下代码:
```rust
@ -222,7 +222,7 @@ let absent_number: Option<i32> = None;
如果使用 `None` 而不是 `Some`,需要告诉 Rust `Option<T>` 是什么类型的,因为编译器只通过 `None` 值无法推断出 `Some` 成员保存的值的类型。
当有一个 `Some` 值时,我们就知道存在一个值,而这个值保存在 `Some` 中。当有个 `None` 值时,在某种意义上,它跟空值具有相同的意义:没有一个有效的值。那么,`Option<T>` 为什么就比空值要好呢?
当有一个 `Some` 值时,我们就知道这个`Option<T>` 中存在一个值,而这个值保存在 `Some` 中。当有个 `None` 值时,在某种意义上,它跟空值具有相同的意义:这个`Option<T>` 没有一个有效的值。那么,`Option<T>` 为什么就比空值要好呢?
简而言之,因为 `Option<T>``T`(这里 `T` 可以是任何类型)是不同的类型,例如,这段代码不能编译,因为它尝试将 `Option<i8>`(`Option<T>`) 与 `i8`(`T`) 相加:
@ -245,11 +245,11 @@ not satisfied
|
```
很好!事实上,错误信息意味着 Rust 不知道该如何将 `Option<i8>``i8` 相加,因为它们的类型不同。当在 Rust 中拥有一个像 `i8` 这样类型的值时,编译器确保它总是有一个有效的值,我们可以自信使用而无需做空值检查。只有当使用 `Option<i8>`(或者任何用到的类型)的时候才需要担心可能没有值,而编译器会确保我们在使用值之前处理了为空的情况。
很好!事实上,错误信息意味着 Rust 不知道该如何将 `Option<i8>``i8` 相加,因为它们的类型不同。当在 Rust 中拥有一个像 `i8` 这样类型的值时,编译器确保它总是有一个有效的值,我们可以放心使用而无需做空值检查。只有当使用 `Option<i8>`(或者任何用到的类型)的时候才需要担心可能没有值,而编译器会确保我们在使用值之前处理了为空的情况。
换句话说,在对 `Option<T>` 进行 `T` 的运算之前必须将其转换为 `T`。通常这能帮助我们捕获到空值最常见的问题之一:期望某值不为空但实际上为空的情况。
不再担心会错误的使用一个空值,会让你对代码更加有信心。为了拥有一个可能为空的值,你必须要显式的将其放入对应类型的 `Option<T>` 中。接着,当使用这个值时,必须明确的处理值为空的情况。只要一个值不是 `Option<T>` 类型,你就 **可以** 安全的认定它的值不为空。这是 Rust 的一个经过深思熟虑的设计决策,来限制空值的泛滥以增加 Rust 代码的安全性。
不再担心会错误的使用一个空值,会让我们更放心所编写的代码。为了拥有一个可能为空的值,你必须要显式的将其放入对应类型的 `Option<T>` 中。接着,当使用这个值时,必须明确的处理值为空的情况。只要一个值不是 `Option<T>` 类型,你就 **可以** 安全的认定它的值不为空。这是 Rust 的一个经过深思熟虑的设计决策,来限制空值的泛滥以增加 Rust 代码的安全性。
那么当有一个 `Option<T>` 的值时,如何从 `Some` 成员中取出 `T` 的值来使用它呢?`Option<T>` 枚举拥有大量用于各种情况的方法:你可以查看[它的文档](https://doc.rust-lang.org/std/option/enum.Option.html)。熟悉 `Option<T>` 的方法将对你的 Rust 之旅非常有用。

Loading…
Cancel
Save