我希望下面的代码能正常工作,但是由于map()
拥有Option
的所有权,并且似乎没有clone()
的{{1}}函数,因此以下内容无法编译。
Option
fn main() {
struct ItemA {
a: String,
b: String,
}
let foo = Some(ItemA {
a: "A String".to_owned(),
b: "B String".to_owned(),
});
// OR
// let foo = None;
let opA: Option<String> = foo.map(|c| c.a);
let opB: Option<String> = foo.map(|c| c.b);
}
如果error[E0382]: use of moved value: `foo`
--> src/main.rs:15:31
|
14 | let opA: Option<String> = foo.map(|c| c.a);
| --- value moved here
15 | let opB: Option<String> = foo.map(|c| c.b);
| ^^^ value used here after move
|
= note: move occurs because `foo` has type `std::option::Option<main::ItemA>`, which does not implement the `Copy` trait
可以拥有opA
的所有权(这样就不必克隆字符串),并且ItemA.a
可以拥有opB
的所有权会很好
是否可以这样做,而不必使用if语句来检查ItemA.b
是Option
还是Some
,展开并单独包装。
答案 0 :(得分:1)
您可以使用map_or_else
。
let (opA, opB) = foo.map_or_else(
|| (None, None),
|c| (Some(c.a), Some(c.b))
);
如果foo
为None
,则调用第一个函数,并返回两个None
。如果foo
是Some
,则调用第二个函数,并将成员拆分为一个元组。
当然,与简单的match
相比,这并不能真正为您节省很多,并且可能会很难遵循。
let (opA, opB) = match foo {
None => (None, None),
Some(c) => (Some(c.a), Some(c.b))
};
顺便说一句,Option
确实实现了Clone
,但是它要求所包含的类型实现Clone
。
答案 1 :(得分:-1)