Menu
CoddyTech

问号运算符“?”

本课属于 Coddy Rust 学习旅程的“逻辑与流程”单元。第 46 课,共 66 课。

处理返回 Result 的函数时,你通常需要处理错误,可以在本地处理,也可以将错误传递给调用函数。Rust 为这种常见模式提供了一个简洁的运算符:问号运算符 ?。

? 运算符可以简洁地传递错误,无需编写冗长的 match 语句。在 Result 后面加上 ?,它会自动解包 Ok 值;如果遇到 Err,则立即从当前函数返回:

fn parse_and_double(s: &str) -> Result<i32, std::num::ParseIntError> {
    let number = s.parse::<i32>()?; // 如果解析失败,就返回错误
    Ok(number * 2) // 如果成功,就将数字乘以 2
}

这相当于编写完整的 match 语句,但简洁得多。如果 s.parse::<i32>() 返回 Ok,? 会提取其中的值,并将其赋给 number。如果返回 Err,? 会立即从整个函数中返回该错误。

注意 ::<i32> 这种语法。这称为turbofish,它会告诉 Rust 要将字符串解析成哪种类型。该函数返回 Result<i32, std::num::ParseIntError>,其中 i32 是成功时的类型,std::num::ParseIntError 是解析失败时返回的错误类型。

? 运算符只能用于返回 Result(或 Option)的函数,因为它需要能够返回错误。

challenge icon

挑战

简单

你会收到两个输入。第一个输入是一个应解析为整数的字符串,第二个输入是另一个同样应解析为整数的字符串。创建一个名为 add_numbers 的函数,它接受两个字符串切片作为参数,并返回 Result<i32, std::num::ParseIntError>。在函数中,使用 ? 运算符解析两个字符串,并将它们的和包装在 Ok 中返回。使用这两个输入调用该函数,并通过 match 处理结果。

要求:

  • 读取第一个输入(第一个数字的字符串),并去除首尾空白
  • 读取第二个输入(第二个数字的字符串),并去除首尾空白
  • 创建一个 add_numbers 函数,它接受两个 &str 参数,并返回 Result<i32, std::num::ParseIntError>
  • 在函数中,使用 ? 运算符将第一个字符串解析为 i32
  • 使用 ? 运算符将第二个字符串解析为 i32
  • 返回 Ok(sum),其中 sum 是两个解析后数字的和
  • 使用这两个输入字符串调用该函数
  • 使用 match 表达式处理 Result
  • 在 Ok(value) 分支中,打印:Sum: [value]
  • 在 Err(_) 分支中,打印:Parsing error

输入:

  • 第一行:表示一个数字的字符串(例如,15)
  • 第二行:表示另一个数字的字符串(例如,27)

输出:

  • 如果两个字符串都是有效数字:Sum: [result]
  • 如果任一字符串无法解析:Parsing error

亲手试试

use std::io;

// TODO: 在这里创建 add_numbers 函数
// 它应接收两个 &str 参数,并返回 Result<i32, std::num::ParseIntError>


fn main() {
    // 读取第一个输入
    let mut input1 = String::new();
    io::stdin().read_line(&mut input1).expect("Failed to read line");
    let input1 = input1.trim();
    
    // 读取第二个输入
    let mut input2 = String::new();
    io::stdin().read_line(&mut input2).expect("Failed to read line");
    let input2 = input2.trim();
    
    // TODO: 用 input1 和 input2 调用 add_numbers
    // TODO: 用 match 处理 Result
    // 如果是 Ok(value),打印 "Sum: [value]"
    // 如果是 Err(_),打印 "Parsing error"
}
quiz icon自我测试

这节课包含一个小测验。开始学习即可作答,并记录你的进度。

逻辑与流程中的所有课

自己练习: Rust 在线编译器