Rust - option<T>

 option<T>

前面的文章中我们介绍了enum的简单使用,本篇文章主要介绍optionoption是标准库定义的另一个枚举,option的应用更加广泛,原因是它设定了一个非常普遍的场景,即要么有值要么没值。

从类型系统的角度来表达这个概念就意味着编译器在编译时就需要检查是否处理了所有应该处理的情况,这样就可以避免在其他编程语言中非常常见的 bug。

Rust语言并没有很多其他语言中有的空值功能。空值Null )是一个值,它代表没有值。在有空值的语言中,变量总是这两种状态之一:空值和非空值。

空值的问题在于当你尝试像一个非空值那样使用一个空值,会出现某种形式的错误。因为空和非空的属性无处不在,非常容易出现这类错误。

而Rust从根本上解决了这个问题,因为Rust没有空值,但是Rust拥有一个可以编码存在或不存在概念的枚举。这个枚举就是option,而且option定义于标准库中,如下代码示例:

enum Option<T> {
    some(T),
    None
}

<T>语法会在后续文章中介绍,它是一个泛型类型参数,option<T>是常规的枚举,Some(T)NoneOption<T> 的成员。

在本文中只需要知道的是 <T> 意味着 Option 枚举的 Some 成员可以包含任意类型的数据。如下述代码示例:

fn main() {
    let some_number = Some(5);
    let some_string = Some("a string");

    let absent_number: Option<i32> = None;
}

如果使用 None 而不是 Some,需要告诉 Rust Option<T> 是什么类型的,因为编译器只通过 None 值无法推断出 Some 成员保存的值的类型。

当有一个 Some 值时,我们就知道存在一个值,而这个值保存在 Some 中。当有个 None 值时,在某种意义上,它跟空值具有相同的意义:并没有一个有效的值。那么,Option<T> 为什么就比空值要好呢?简而言之,因为 Option<T>T(这里 T 可以是任何类型)是不同的类型,编译器不允许一个像肯定非空的值和肯定非空的值进行比较或者运算,比如下述代码示例:

fn main() {
    let x: i8 = 5;
    let y: Option<i8> = Some(5);

    let sum = x + y;
}

如果运行上述代码,则会抛出下面的异常:

error[E0277]: the trait bound `i8: std::ops::Add<std::option::Option<i8>>` is
not satisfied
 -->
  |
5 |     let sum = x + y;
  |                 ^ no implementation for `i8 + std::option::Option<i8>`
  |

异常的意思就是Rust 不知道该如何将 Option<i8>i8 相加,因为它们的类型不同。当在 Rust 中拥有一个像 i8 这样类型的值时,编译器确认为它总是有一个有效的值。我们无需任何顾虑自信使用而无需做空值检查。只有当使用 Option<i8>(或者任何用到的类型)的时候需要担心可能没有值。

换句话说,在对 Option<T> 进行 T 的运算之前必须将其转换为 T。通常帮助我们捕获到空值最常见的问题之一:假设某值不为空但实际上为空的情况。

如果程序中可能会出现值为空的值,就必须现实的将其放入对应类型的 Option<T> 中。当使用这个值时,必须明确的处理值为空的情况。这是 Rust 的一个经过深思熟虑的设计决策,来限制空值的泛滥以增加 Rust 代码的安全性。

最后感谢每一个认真阅读我文章的人,礼尚往来总是要有的,这些资料,对于【软件测试】的朋友来说应该是最全面最完整的备战仓库,虽然不是什么很值钱的东西,如果你用得到的话可以直接拿走:

这些资料,对于【软件测试】的朋友来说应该是最全面最完整的备战仓库,这个仓库也陪伴上万个测试工程师们走过最艰难的路程,希望也能帮助到你! 

相关推荐

  1. Rust Option类型详解

    2024-01-22 01:36:02       54 阅读
  2. Rust的Vec<T

    2024-01-22 01:36:02       68 阅读
  3. Rust 中的 Option、Result 和 ? 运算符

    2024-01-22 01:36:02       57 阅读
  4. Optional

    2024-01-22 01:36:02       54 阅读
  5. Rust语言中Option和Result两种类型的使用

    2024-01-22 01:36:02       39 阅读
  6. Rust 的 Arc<Mutex<T>> 的用法示例源代码

    2024-01-22 01:36:02       45 阅读
  7. 设计一个Rust线程安全栈结构 Stack<T

    2024-01-22 01:36:02       44 阅读
  8. 安装transforers时报错:error: can‘t find Rust compiler

    2024-01-22 01:36:02       32 阅读
  9. Rust 泛型使用过程中的 <T> 和 ::<T> 的区别

    2024-01-22 01:36:02       42 阅读

最近更新

  1. docker php8.1+nginx base 镜像 dockerfile 配置

    2024-01-22 01:36:02       98 阅读
  2. Could not load dynamic library ‘cudart64_100.dll‘

    2024-01-22 01:36:02       106 阅读
  3. 在Django里面运行非项目文件

    2024-01-22 01:36:02       87 阅读
  4. Python语言-面向对象

    2024-01-22 01:36:02       96 阅读

热门阅读

  1. Code Review是什么?怎么进行代码审查?

    2024-01-22 01:36:02       52 阅读
  2. 【小白向】MMDeploy安装部署|暗坑标注版

    2024-01-22 01:36:02       65 阅读
  3. 第五章:大模型的数据

    2024-01-22 01:36:02       61 阅读
  4. CloudCompare 二次开发(26)——RANSAC分割多个平面

    2024-01-22 01:36:02       60 阅读
  5. QT基础篇(12)QT5多线程

    2024-01-22 01:36:02       46 阅读
  6. ElasticSearch使用篇

    2024-01-22 01:36:02       49 阅读
  7. AcWing 787. 归并排序(模板题详解)

    2024-01-22 01:36:02       58 阅读