Rust 中的 Option、Result 和 ? 运算符

Option类型

在编程中,我们经常会遇到某个值或者某个数据域可能存在,可能不存在;如果存在,它才会包含某个值。在C/C++ 中,一般会使用 NULL 表示不存在这种情况,而 NULL 是很多异常和安全的祸根。Rust 从语言层面就删除了对 NULL 的支持,并在标准库中引入 Option 类型,用于表示上述那种可能存在可能不存在的情况。

Option 类型定义如下,它包含在 prelude 中,可以直接引用。

pub enum Option<T> {
    None,
    Some(T),
}

Result 类型

一个功能、服务的执行结果分为2类:(1)执行成功,返回执行结果;(2)执行失败,返回失败原因。在传统编程语言中,一般使用同一类型的返回值表示这两类结果,这会容易出现混淆。Rust 标准库引入 Result 类型,它是一个 enum 类型,用不同的枚举值类型表示两类结果。同时,基于Rust enum 类型的优点,将执行结果和失败原因包含在其中。借助特定声明式标记#[must_use] ,在代码没有处理这个结果时,给出编译警告,提供程序员优化代码。

Result 类型定义如下,它包含在 prelude 中,可以直接应用。

enum Result<T, E> {
   Ok(T),
   Err(E),
}

? 运算符

良好的 Rust 代码,很多时候,函数返回的是 Result 类型,如果每个调用都要处理一次返回值,代码就比较繁琐,很多时候,当调用的子函数返回的是 Err 时,我们只是想把这个 Err 传导到调用者函数,借助 ? 运算符,我们就可以实现这样功能。如果子函数返回的是 Ok 时,函数继续往下走;如果返回的是 Err,函数返回并返回这个 Err,由更上层的调用者负责具体处理 Result。

fn fun1() -> Result<int32, String> {

}

fn fun2() -> Result<int32, String> {

}

fn fun1() -> Result<int32, String> {

}


/// 传统处理方式
fn fun() -> Result<int32, String> {
	if let Err(e) = fun1() {
    return Err(e);
  }

	if let Err(e) = fun2() {
    return Err(e);
  }

	if let Err(e) = fun3() {
    return Err(e);
  }

	Ok(i)
}

/// 借助 ? 运算符
fn fun() -> Result<int32, String> {
	fun1()?;
  fun2()?;
  fun3()?;

	Ok(i)
}

/// 当然,在更上层的调用函数中,还是需要程序员处理这个Result的。比如
fn main() {

  // fun() 的调用者 main() 返回值不是 Result,就无法再向上传导了。
  // 或者fun() 的调用者需要主动对 Err 做处理时,就不要再直接向上传导。
	let ret = fun();

  match ret {
    Ok(i) => {
      println!("success, ret is {i}");
    }
    Err(e) => {
      println!("Fail, error reason is {e:}");
    }
  }
}

? 运算符同样适用于 Option,当遇到 None 时,直接返回并向上传导。

相关推荐

  1. Rust Option、Result ? 运算符

    2024-01-23 14:04:01       57 阅读
  2. Rust&strString关系

    2024-01-23 14:04:01       41 阅读
  3. Rust Cell RefCell

    2024-01-23 14:04:01       44 阅读
  4. Rust 模式匹配& ref

    2024-01-23 14:04:01       38 阅读
  5. C++::运算符

    2024-01-23 14:04:01       28 阅读
  6. 第二章:c语言表达式运算符

    2024-01-23 14:04:01       30 阅读
  7. php常见运算符使用方法

    2024-01-23 14:04:01       28 阅读
  8. python逻辑运算符and or 优先级问题。

    2024-01-23 14:04:01       24 阅读

最近更新

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

    2024-01-23 14:04:01       94 阅读
  2. Could not load dynamic library ‘cudart64_100.dll‘

    2024-01-23 14:04:01       100 阅读
  3. 在Django里面运行非项目文件

    2024-01-23 14:04:01       82 阅读
  4. Python语言-面向对象

    2024-01-23 14:04:01       91 阅读

热门阅读

  1. Rust 并发

    2024-01-23 14:04:01       46 阅读
  2. 树莓派ubuntu:CSI接口摄像头安装驱动程序及测试

    2024-01-23 14:04:01       53 阅读
  3. UNITY BUILD加速cmake 编译

    2024-01-23 14:04:01       51 阅读
  4. VSCode 中 Tab 键突然不能缩进了

    2024-01-23 14:04:01       51 阅读
  5. 边缘计算的挑战和机遇

    2024-01-23 14:04:01       60 阅读
  6. R语言【cli】——ansi_strtrim():截断ANSI字符串

    2024-01-23 14:04:01       54 阅读
  7. NLP深入学习(七):词向量

    2024-01-23 14:04:01       55 阅读
  8. promise

    2024-01-23 14:04:01       57 阅读