当前位置: 首页 > article >正文

【Rust自学】6.2. Option枚举

喜欢的话别忘了点赞、收藏加关注哦,对接下来的教程有兴趣的可以关注专栏。谢谢喵!(=・ω・=)

6.2.1. 什么是Option枚举

它定义于标准库中,在Prelude(预导入模块)中,负责描述这样的场景:
某个值有可能存在,是哪种数据类型,或者就是不存在

6.2.2. Rust没有Null

在大部分其他语言中都有Null这个值,它代表没有值

在那些语言里,一个变量可以处于两种状态:

  • 空值(Null
  • 非空

Null的发明者托尼·霍尔 (Tony Hoare) 在 2009 年的演讲“Null References: The Billion Dollar Mistake”中说道:

I call it my billion-dollar mistake. At that time, I was designing the first comprehensive type system for references in an object-oriented language. My goal was to ensure that all use of references should be absolutely safe, with checking performed automatically by the compiler. But I couldn’t resist the temptation to put in a null reference, simply because it was so easy to implement. This has led to innumerable errors, vulnerabilities, and system crashes, which have probably caused a billion dollars of pain and damage in the last forty years.
我称之为我的十亿美元错误。当时,我正在设计第一个面向对象语言的综合引用类型系统。我的目标是确保所有引用的使用都绝对安全,并由编译器自动执行检查。但我无法抗拒放入空引用的诱惑,只是因为它很容易实现。这导致了无数的错误、漏洞和系统崩溃,在过去四十年中可能造成了数十亿美元的痛苦和损失。

Null的问题非常的显而易见,连其发明者都不认为这是个好东西。举个例子:比如一个变量是字符串类型的,这个变量需要与其他的字符串进行连接,而实际上这个变量是Null值,那么在连接时就会产生错误。对于Java用户来说,最常见的错误就是NullPointerException。一句话总结,当你尝试像使用非Null值那样使用Null值时,就会引起某种错误

因此,Rust没有提供Null。但是针对Null试图表达的概念(Null是当前无效或由于某种原因不存在的值)Rust提供了类似的枚举叫Option<T>

6.2.3. Option<T>

它在标准库中的定义是这样的:

enum Option<T>{
	Some(T),
	None,
}
  • Some这个变体可以关联某些数据,其数据类型就是T<T>实际上是泛型参数(以后会讲)
  • None是其另外一个变体,但不会关联任何数据,因为它代表的是值不存在的情况

因为它包含在预导入模块,所以可以直接使用Option<T>Some(T)None

看个例子:

fn main(){  
    let some_number = Some(5);  
    let some_char = Some('e');  
  
    let absent_number: Option<i32> = None;  
}
  • 对于前两个语句,其值都写在括号里了,所以Rust编译器能够推断出其数据类型,比如some_number的类型是Option<i32>some_char的类型是Option<&str>,当然你也可以显式声明,但没必要,除非你想指定某个类型。
  • 对于最后语句,由于赋的值是None这个变体,编译器无法根据None推断出Option<T>T代表的到底是什么类型,所以就需要显式声明具体的类型。所以在这里写的是Option<i32>

在这个例子中,前两个变量就是有效的值,而最后的变量就是没有有效的值。

6.2.4. Option<T>的优点

  • 在Rust里,Option<T>TT可以是任何的数据类型)是不同的类型,不可以把Option<T>当作T
  • 若想使用Option<T>中的T,必须先将它转换为T。这避免了程序员忽略了空值的可能性,直接操作了可能为空的变量,Rust 的 Option<T> 设计迫使开发者显式处理这些情况。
    比如在C#中先string a = null;string b = a + '12345';如果不检查a是否为空值(或者说忽略了a是空值的可能性)那么在运行到第二行时就会引起错误。
    而在Rust里,只要这个值的类型不是Option<T>,那么这个值就肯定不是空的。

举个例子:

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

如果运行这段代码,编译器就会报错:

error[E0277]: cannot add `Option<i8>` to `i8`
 --> src/main.rs:5:17
  |
5 |     let sum = x + y;
  |                 ^ no implementation for `i8 + Option<i8>`
  |
  = help: the trait `Add<Option<i8>>` is not implemented for `i8`
  = help: the following other types implement trait `Add<Rhs>`:
            `&i8` implements `Add<i8>`
            `&i8` implements `Add`
            `i8` implements `Add<&i8>`
            `i8` implements `Add`

报错内容的意思就是无法把Option<i8>i8这两者变量的类型进行相加,因为它们不是同一种类型。

那怎么让xy进行相加呢?很简单,把yOption<i8>转为i8就行:

fn main() {  
    let x: i8 = 5;  
    let y: Option<i8> = Some(5);  
  
    let sum = match y {  
        Some(value) => x + value, // 如果 y 是 Some,则解包并相加  
        None => x,               // 如果 y 是 None,则返回 x    
    };  
}

http://www.kler.cn/a/451609.html

相关文章:

  • mysql 查询优化之字段建立全文索引
  • 记录一个SVR学习
  • 被裁20240927 --- 嵌入式硬件开发 前篇
  • 272-1路万兆光纤SFP+和1路千兆网络 FMC子卡模块
  • Android 常用布局
  • Chrome 关闭自动添加https
  • Log4j1.27配置日志输出级别不起效
  • 《C++设计模式》工厂模式
  • 抖音视频下载去水印工具推荐
  • DATAHUB FRONTEND 开发测试:
  • WebGIS实战开源项目:智慧机场三维可视化(学习笔记)
  • “开启智能新时代”——机器连接与边缘计算
  • 微信小程序:解决顶部被遮挡的问题
  • Python8-写一些小作业
  • QT的错误记录:同文件的的两个QThread子类信号槽关联
  • MySQL for update skip locked 与 for update nowait
  • vue前端编译报错解决方法
  • 007-spring-bean的相关配置(重要)
  • 2025人工智能与教育科学国际会议(AIES 2025)
  • stm32硬件iic
  • Java中classpath的基本概念和配置方法
  • 【C#】可以点击单行文本的Popup控件
  • 如何使用Python调用SD模型进行文生图
  • 仓颉编程语言深入教程:基础概念和数据类型
  • [SZ901]FPGA程序固化工具使用方法
  • 国产之光--仓颉编程语言的实战案例分析