当反序列化深度嵌套的 struct (例如来自JSON)时,必须遍历多个类型的情况并不少见.

例如:

let foo = Foo {
    x: Some(Bar {
        y: Some(Baz {
            z: Some(42),
        })
    })
};

有没有一种惯用的链接选项的方法来访问深度嵌套的值?

到目前为止,我有以下内容,但在其他支持可选链接的语言中,它们都不如foo.x?.y?.z简洁:

let z = foo.x.as_ref().and_then(|x| x.y.as_ref()).and_then(|y| y.z);
let z = foo.x.as_ref().and_then(|x| x.y.as_ref()?.z);
let z = (|| foo.x.as_ref()?.y.as_ref()?.z)();

看起来try_block功能可能很适合,但目前不稳定.

let z = try { foo.x.as_ref()?.y.as_ref()?.z };

推荐答案

正如你所说,try街区将是完美的 Select .

同时,您可以利用?在函数中起作用的事实,将表达式封装在闭包中并调用它:

let z = (|| foo.x.as_ref()?.y.as_ref()?.z )();

您可以编写一个简单的宏,让它变得更好:

macro_rules! tryit {
    ($($e: tt)+) => {
        (|| { $($e)+ })()
    }
}

其工作原理与try块基本相同:

let z = tryit! { foo.x.as_ref()?.y.as_ref()?.z };

Rust相关问答推荐

基于对vec值的引用从该值中删除该值

阻止websocket中断的中断中断的终端(操作系统错误4)

什么是Rust惯用的方式来使特征向量具有单个向量项的别名?

Tokio_Postgres行上未显示退回特性的生存期,且生命周期 不够长

一种随机局部搜索算法的基准(分数)

将serde_json读入`VEC<;T&>;`( rust 色)时出现问题

在Rust中声明和定义一个 struct 体有什么区别

如何在Rust中基于字符串 Select struct ?

Rust将String上的迭代器转换为&;[&;str]

使用 serde::from_value 反序列化为泛型类型

实现 Deref 的 struct 可以返回对外部数据的引用吗?

是否可以在不直接重复的情况下为许多特定类型实现一个函数?

tokio::sync::broadcast::Receiver 不是克隆

Rust 重写函数参数

如何以与平台无关的方式将OsString转换为utf-8编码的字符串?

为什么这个闭包没有实现Fn?

&self 参数在 trait 的功能中是必需的吗?

Rust 将特性传递给依赖项

如何在 use_effect_with_deps 中设置监听器内的状态?

为什么我不能将元素写入 Rust 数组中移动的位置,但我可以在元组中完成