rust - 有没有办法在 Option 中拆分变量而不必使用 if 语句?

标签 rust ownership

我希望下面的代码可以工作,但是因为 map()取得 Option 的所有权, 而且似乎没有 clone() 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可以取得 ItemA.b 的所有权

这是否可以在不必使用 if 语句来检查 Option 的情况下完成?是SomeNone ,解包,并单独包装它。

最佳答案

您可以使用 map_or_else .

let (opA, opB) = foo.map_or_else(
    || (None, None),
    |c| (Some(c.a), Some(c.b))
);

如果 fooNone,则调用第一个函数,并返回两个 None。如果 fooSome 并将成员拆分为一个元组,则调用第二个函数。

当然,与简单的匹配相比,这并不能真正为您节省多少,而且可能更难理解。

let (opA, opB) = match foo {
    None => (None, None),
    Some(c) => (Some(c.a), Some(c.b))
};

顺便说一句,Option 确实实现了 Clone,但它要求包含的类型实现了 Clone

关于rust - 有没有办法在 Option 中拆分变量而不必使用 if 语句?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53421617/

相关文章:

parallel-processing - 不能使用 Rayon 的 `.par_iter()`

closures - 我的代码中的非法移动在哪里?

rust - 字符串是 Drop 还是 Copy?

winapi - 如何使用 Rust 和 winapi crate 在 Windows 中创建事件订阅?

rust - 带有使用rust 的exec “tail -f xxx”

rust - 为什么使用freetype-rs会报链接错误?

rust - 如何在 Rust 的内循环中正确移动所有权?

Rust,在迭代中需要一个可变的 Self 引用

rust - 如何使用消耗该成员本身的成员方法替换结构成员?

rust - 使用移动匹配变量的匹配语句引发编译器错误