我有一个具有不同变体的枚举,我想找到第一个匹配的变体,然后通过返回变体值或将其Map到其他值来转换它。
在Scala中,我会使用case类来执行类似以下操作:
data.collectFirst{ case d: DataD => d.data }
在Rust中,我必须进行两次模式匹配才能达到相同的结果。有没有办法让它不那么冗长?
enum MyData {
DataA(String),
DataB(u64),
DataC(bool),
DataD { data: String, val: u32 },
}
fn main() {
// test data
let data = vec![
MyData::DataB(42),
MyData::DataD {
data: "meaning of life".to_owned(),
val: 42,
},
MyData::DataC(false),
];
// find first one that matches and map it
let found: Option<String> = data
.iter()
.find(|d| match **d {
MyData::DataD { .. } => true,
_ => false,
})
.and_then(|d| match *d {
MyData::DataD { ref data, .. } => Some(data.to_owned()),
_ => None,
});
}
2条答案
按热度按时间yhqotfr81#
从Rust 1.30开始,可以使用
Iterator::find_map
:在此之前,您可以使用
Iterator::filter_map
和Iterator::next
:我真的不喜欢在迭代器链中使用大的
match
语句,所以我通常会在MyData
上创建一个方法来代替:事实上,我的很多枚举都有这样的模式:
我甚至创建了一个板条箱来自动派生这些函数。我从来没有发表过它,因为我很确定类似的东西已经存在,只是我还没有找到它...
zkure5ic2#