Rust中能否在代码块作用域内使用?运算符?有什么替代实现方案?
解决方案
方案1:使用nightly Rust的try_blocks特性(最贴合你的预期写法)
如果你可以接受使用nightly版本的Rust,官方提供的try块特性完全匹配你的需求,只需要在crate根添加特性声明,然后在你需要捕获错误的代码块前加上try关键字即可:
// 放在crate根的lib.rs或main.rs顶部 #![feature(try_blocks)]
你的业务代码可以直接写成你预期的形式,仅需增加try关键字:
fn do_something() { let i = try { let w = function1()?; let x = function2(z)?.function3()?; x.y()? }; if let Ok(item) = i { // 执行成功后的逻辑 } else { // 任意一步出错后的处理逻辑 } // 后续代码 }
try块会自动捕获块内所有?抛出的错误,最终整个块的返回值是Result类型,完全符合你的使用需求。目前该特性已经进入稳定化评估阶段,未来会进入稳定版本。
方案2:稳定版本通用的立即执行闭包
目前稳定版本的Rust最常用的实现方式就是使用立即执行的返回Result的闭包,这是当前社区公认的惯用写法,并不存在不符合Rust规范的问题:
fn do_something() { let i = (|| { let w = function1()?; let x = function2(z)?.function3()?; Ok(x.y()?) })(); if let Ok(item) = i { // 执行成功后的逻辑 } else { // 错误处理逻辑 } // 后续代码 }
如果块内的错误类型统一,不需要手动标注闭包的返回类型,编译器可以自动推导。
方案3:短调用链使用and_then链式调用
针对你提到的短链式调用场景,可以直接使用Result自带的and_then方法串联调用,不需要额外的块结构:
let i = function1() .and_then(|v| v.function2()) .and_then(|v| v.function3());
这种写法无额外特性依赖,完全兼容稳定版本,适合逻辑简单的调用链路。
内容的提问来源于stack exchange,提问作者zombiesauce
相关产品推荐
相关产品推荐

