Option::and_then函数可以简化此代码:

let foo = Some(1);
let bar = match foo {
    Some(i) => Some(i + 1),
    None => None,
};
println!("Foo: {:?}", foo);

对此:

let foo = Some(1);
let bar = foo.and_then(|i| Some(i + 1));
println!("Foo: {:?}", foo);

如果我对String个进行同样的try ,它不会编译:

let foo = Some("bla".to_string());
let bar = foo.and_then(|ref f| Some(f.clone()));
println!("Foo: {:?}", foo);
error[E0382]: use of moved value: `foo`
 --> src/main.rs:4:27
  |
3 |     let bar = foo.and_then(|ref f| Some(f.clone()));
  |               --- value moved here
4 |     println!("Foo: {:?}", foo);
  |                           ^^^ value used here after move
  |
  = note: move occurs because `foo` has type `std::option::Option<std::string::String>`, which does not implement the `Copy` trait

然而,相应的match个表达式起作用:

let foo = Some("bla".to_string());
let bar = match foo {
    Some(ref f) => Some(f.clone()),
    None => None,
};
println!("Foo: {:?}", foo);

有没有办法像我的第一个例子那样用整数来缩短这个匹配表达式?

Code on playground

  • 在这个最小的例子中,我可以使用map,但在我的实际代码中,我调用了另一个返回Option的函数,所以我真的需要and_then.只是我不想用一个不影响问题的额外函数使示例过于复杂.

  • 我真的需要在之后使用foo,否则就不会有任何问题(事实上,foo是由一个闭包捕获的,我需要多次使用,老兄!我很难找到编译器为什么一直拒绝我的代码!错误the trait FnMut... is not implemented for the type [closure@...]没有给出太多指示,说明为什么不这样做).

  • 我在这个例子中使用了clone,因为我想要一个使用字符串的简单操作.在实际代码中,foo不是字符串(它是Regex),我也不是在闭包中克隆它(我是在字符串上应用它并处理结果).此外,此代码将被多次调用,因此避免不必要的分配和复制非常重要.

推荐答案

解释

首先:这里您实际想要使用的方法是map,因为您只想更改内部值.如果在闭包中创建另一个Option,则and_then很有用.

回答你的问题:你不能再访问foo是正确的.如果你看看函数声明...

fn and_then<U, F: FnOnce(T) -> Option<U>>(self, f: F) -> Option<U>
//                                        ^^^^

... 第一个参数是self.这意味着该方法消耗self(获得所有权),因此foo被移动到该方法中,无法再使用.

解决方案

如果之后只需要bar(通常是这样),你应该只打印bar.如果你真的也需要foo,你可以这样做:

let bar = foo.as_ref().map(|s| s.clone());

as_ref创建一个新的Option,它只保存对原始内部变量的引用.引用是Copy种类型,因此map可以安全地使用Option种.

Rust相关问答推荐

是否有可能同时避免不兼容的不透明类型和代码重复?

这种获取-释放关系是如何运作的?

在Rust中,在实现特征`Display`时,如何获取调用方指定的格式?

在Rust中,如果Result是Err,运行副作用(如日志(log)记录)的惯用方法是什么

我应该将哪些文件放入我的GitHub存储库

为什么不';t(&;mut-iter).take(n)取得iter的所有权?

为相同特征的特征对象使用 move 方法实现特征

有没有办法隐式绑定 let/match 操作的成员?

不安全块不返回预期值

如何在 Rust 中将 Vec> 转换为 Vec>?

错误:将自定义 proc_macro 与用Rust 的宝贝编写的属性一起使用时,无法在此范围内找到属性

我什么时候应该使用特征作为 Rust 的类型?

在 Rust 中如何将值推送到枚举 struct 内的 vec?

为什么 &i32 可以与 Rust 中的 &&i32 进行比较?

使用部分键从 Hashmap 中检索值

是否有适当的方法在参考 1D 中转换 2D 数组

当 `T` 没有实现 `Debug` 时替代 `unwrap()`

有没有办法阻止 rust-analyzer 使非活动代码变暗?

在 Rust 中退出进程

如何在 Rust 的泛型函​​数中同时使用非拥有迭代器和消费迭代器?