推荐答案
在 Rust 中,? 运算符用于简化错误处理。它通常用于返回 Result 或 Option 类型的函数中。当 Result 是 Err 或 Option 是 None 时,? 运算符会提前返回错误或 None,否则它会解包 Result 或 Option 中的值并继续执行。
本题详细解读
? 运算符的基本用法
? 运算符主要用于简化错误处理代码。假设你有一个返回 Result<T, E> 的函数,你可以在函数内部使用 ? 来处理可能的错误。如果 Result 是 Ok(value),? 会解包并返回 value;如果 Result 是 Err(e),? 会提前返回 Err(e)。
// www.javascriptcn.com code example
fn divide(a: i32, b: i32) -> Result<i32, String> {
if b == 0 {
return Err("Division by zero".to_string());
}
Ok(a / b)
}
fn calculate(a: i32, b: i32) -> Result<i32, String> {
let result = divide(a, b)?;
Ok(result + 10)
}在上面的例子中,divide(a, b)? 会检查 divide 函数的返回值。如果 divide 返回 Err,calculate 函数会立即返回该错误;否则,result 会被赋值为 divide 返回的 Ok 值。
? 运算符与 Option 类型
? 运算符也可以用于 Option 类型。如果 Option 是 None,? 会提前返回 None;否则,它会解包 Some(value) 并继续执行。
// www.javascriptcn.com code example
fn find_username(user_id: u32) -> Option<String> {
// 假设这是一个查找用户名的函数
if user_id == 1 {
Some("Alice".to_string())
} else {
None
}
}
fn greet_user(user_id: u32) -> Option<String> {
let username = find_username(user_id)?;
Some(format!("Hello, {}!", username))
}在这个例子中,find_username(user_id)? 会检查 find_username 的返回值。如果 find_username 返回 None,greet_user 函数会立即返回 None;否则,username 会被赋值为 find_username 返回的 Some 值。
? 运算符的限制
? 运算符只能在返回 Result 或 Option 的函数中使用。如果你在一个返回 () 或其他类型的函数中使用 ?,编译器会报错。
fn invalid_use() {
let result: Result<i32, String> = Ok(42);
let value = result?; // 错误:`?` 不能在返回 `()` 的函数中使用
}? 运算符与 try! 宏
在 Rust 的早期版本中,try! 宏用于处理 Result 类型的错误。? 运算符是 try! 宏的语法糖,提供了更简洁的错误处理方式。
fn old_way(a: i32, b: i32) -> Result<i32, String> {
let result = try!(divide(a, b));
Ok(result + 10)
}在现代 Rust 代码中,推荐使用 ? 运算符来替代 try! 宏。