Rust中的结果类型和match vs if is_ok [closed]

thtygnil  于 2023-05-07  发布在  其他
关注(0)|答案(1)|浏览(145)

已关闭,此问题需要更focused。目前不接受答复。
**想改善这个问题吗?**更新问题,使其仅通过editing this post关注一个问题。

4天前关闭。
Improve this question
处理Result<T, E>类型似乎有两种明显的方法。
第一个是使用match,我相信它在Rust Book等参考文献中使用得最频繁。

match some_result {
    Ok(value) => {

    },
    Err(error) => {

    },
}

然而,使用ifis_ok()unwrap()的组合来完成同样的事情是相当简单的。

if some_result.is_ok() {
    let some_value = some_result.unwrap();

}
else {

}

匹配稍微优雅一些,因为它不需要额外的赋值语句,您已经有了传递给Ok的名称中的类型。
unwrap()unwrap_err()有一个伙伴返回错误,如果结果是Ok而不是Err,则会死机。
这意味着可以执行以下操作:

if some_result.is_ok() {
    let some_value = some_result.unwrap();

}
else {
    let error = some_result.unwrap_err(); // panic if `Ok`

}

然而,有时if语句更容易使用,因为match要求所有分支在它们返回的类型中兼容。(如果()是返回类型,则很简单。)
似乎最合适的选择是上下文相关的。
我对上述几点的理解是否正确,或者我是否误解了什么,即应该使用match而不是if

ukqbszuj

ukqbszuj1#

这个问题充满了误解。
似乎有两种明显的方式
不止两个。首先,您没有考虑?操作符,该操作符允许您优雅地向调用者提出错误。
有时if语句更容易使用,因为match要求所有分支在它们返回的类型中是兼容的。
if在用作表达式时具有 * 完全相同的效果 *。无论您打算使用if还是match,所有条件表达式都必须计算为相同的类型。

let r = Ok(5);
if r.is_ok() {
    r.unwrap()
} else {
   // fails to compile, must return an integer
}

因此,赞成第二种形式的观点是没有实际意义的。正如您所指出的,如果意图是执行副作用而不从matchif表达式返回某些内容,则可以通过在块中追加分号来使它们返回()
似乎最合适的选择是上下文相关的。
这个决定一点也不模糊!几乎没有一个很好的理由执行if result.is_*(),然后执行unwrap。它不仅更冗长,看起来更难看,而且对结果进行冗余检查的可能性也更高。
参见:

相关问题