Rust中使用早期返回处理错误的惯用方式

4

我目前有以下代码来处理不想传播或继续函数的错误情况。这种情况是Web服务器控制器的用例,我更喜欢手动处理可能出现的错误-这就是为什么返回类型是HttpResponse的原因。

我想知道是否有一种方法可以在没有unwrap调用的情况下完成此操作,因为据我所知,在此时编译器应该知道有一种方法可以解包到一个值,而没有恐慌的风险。

    // ...
    
    let result: Result<u8, Error> = func_that_could_error();
    if result.is_err() {
        return HttpResponse::InternalServerError();
    }
    let value: u8 = result.unwrap();
    
    // ...

1
let value = result.map_err (|_| HttpResponse::InternalServerError())?; - Jmb
让我们把结果进行匹配,如果是错误则返回一个 HTTP 500 错误响应(HttpResponse::InternalServerError()),否则将 v 的值赋给 value 变量。 - Jmb
1个回答

5

如果可以,使用?

let value = func_that_could_error()?;

如@Jmb所建议的那样,可以将它可选地映射为您的错误:

let value = func_that_could_error()
    .map_err(|_| HttpResponse::InternalServerError())?;

否则,使用 let else:
let Ok(value) = func_that_could_error() else {
    return HttpResponse::InternalServerError();
};

或者对于 Rust < 1.65,使用 match

let value = match func_that_could_error() {
    Err(_) => return HttpResponse::InternalServerError(),
    Ok(v) => v,
};

你的 let-else 示例中多了一个 if - Jmb
1
同时,虽然 let-else 仍不稳定,但 guard 通过宏实现了它(有一些限制),并且非常可靠,在稳定版上已经运行了多年。基本上将整个内容(除了尾随的 ;)包装在 guard!() 中即可完成。 - Masklinn
注意:如果您的函数返回类型是 ResultOption,则只能使用 ? - aedm
1
感谢提供的选项。let-else 看起来很理想,但目前还无法稳定使用。我一定会关注 RFC 的进展。 - JamesGill
@JamesGill 不用谢。我添加了 match 的替代方案。 - Acorn
在处理 Option 类型时,使用 ok_or(<err_type>) 代替 Return。;-) - jaques-sam

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接