Rust 中 `?` 操作符的作用


Rust 中 ? 操作符的作用

Rust 中的 ? 操作符用于错误传播,它提供了一种简洁的方式来处理 ResultOption 类型的错误情况。

主要功能:

  1. 自动错误传播:当 ? 应用于 Result 类型时,如果值是 Err,则立即返回该错误
  2. 值提取:如果值是 Ok,则提取其中的值继续执行

Python 中的等价概念:

在 Python 中,Rust 的 ? 操作符类似于使用异常处理,但 Rust 的方式更加显式和类型安全。

# Python 中的异常处理方式(隐式)
def get_value_from_row(row, index):
    try:
        return row.get(index)  # 可能抛出异常
    except SomeDatabaseError as e:
        # 需要显式捕获和处理异常
        raise e  # 或者返回默认值
# 更接近 Rust ? 操作符行为的伪代码概念
def get_value_from_row_with_propagation(row, index):
    result = row.get(index)
    if result.is_error():  # 类似 Result::Err
        return result  # 立即返回错误,不继续执行
    return result.unwrap()  # 返回成功值

在代码中:

enable: row.get(3)?

这行代码的作用是:

  • 调用 row.get(3) 获取数据库行中的第4个字段
  • row.get(3) 返回 Result<T, Error> 类型
  • 如果获取成功(Ok),提取值并赋给 enable 字段
  • 如果获取失败(Err),? 会立即将错误传播给外层函数处理

对比示例:

// 使用 ? 操作符(简洁写法)
fn example_with_question_mark(row: &Row) -> Result<PremissonStrategyResponse, Error> {
    Ok(PremissonStrategyResponse {
        id: row.get(0)?,
        name: row.get(1)?,
        white_list_ids: row.get(2)?,
        enable: row.get(3)?,
    })
}
// 不使用 ? 操作符(冗长写法)
fn example_without_question_mark(row: &Row) -> Result<PremissonStrategyResponse, Error> {
    let id_result = row.get(0);
    if id_result.is_err() {
        return Err(id_result.unwrap_err());
    }
    let id = id_result.unwrap();
    let name_result = row.get(1);
    if name_result.is_err() {
        return Err(name_result.unwrap_err());
    }
    let name = name_result.unwrap();
    // ... 重复类似的错误检查
    Ok(PremissonStrategyResponse {
        id,
        name,
        white_list_ids,
        enable,
    })
}

? 操作符大大简化了错误处理代码,使代码更加简洁和易读。

声明:一代明君的小屋|版权所有,违者必究|如未注明,均为原创|本网站采用BY-NC-SA协议进行授权

转载:转载请注明原文链接 - Rust 中 `?` 操作符的作用


欢迎来到我的小屋