原始变量的生命周期不够长

3

这段代码存在错误:

let a: Vec<_> = (1..10).flat_map(|x| (1..x).map(|_| x)).collect();

错误信息:
error[E0597]: `x` does not live long enough
 --> src/main.rs:2:57
  |
2 |     let a: Vec<_> = (1..10).flat_map(|x| (1..x).map(|_| x)).collect();
  |                                                     --- ^-          - borrowed value needs to live until here
  |                                                     |   ||
  |                                                     |   |borrowed value only lives until here
  |                                                     |   borrowed value does not live long enough
  |                                                     capture occurs here

但为什么?

这是一种原始类型,即无论如何都应该进行克隆。

我哪里理解错了吗?


@Boiethios 是的,但在我的情况下应该是(最终):1..x, x..y, y..z;当然我们可以用过滤器删除其余部分,但我认为这是错误的。 - Igor Chubin
@Boiethios: 但是我仍然不理解,如何克隆该值?(move非常完美)。问题是:为什么我应该借用或移动原始值,而不是简单地复制呢?我该如何强制执行? - Igor Chubin
移动会复制整数,因为它是“可复制”的。对于这些类型,移动和复制是相同的事情。你可以多次移动它,编译器不会抱怨。如果你想要一个显式的副本,可以调用clone()方法。 - Boiethios
@Boiethios:在发布问题到Stackoverflow之前,我尝试过首先使用clone,但没有帮助。我应该在哪里添加.clone() - Igor Chubin
让我们在聊天中继续这个讨论 - Boiethios
显示剩余5条评论
1个回答

3

这不起作用是因为在执行 map(|_| x) 时,你通过引用捕获了 x。由于 x 不是闭包局部变量,所以它被借用了。如果不想借用 x,则必须使用 move 关键字:

let a: Vec<_> = (1..10).flat_map(|x| (1..x).map(move |_| x)).collect();

但这种写法更为惯用(输出相同的结果):
use std::iter::repeat;
let b: Vec<_> = (2..10).flat_map(|x| repeat(x).take(x - 1)).collect();

关于“为什么”的问题:有些人可能想借用可复制数据,因此捕获规则相同:

  • 默认情况下:通过引用方式捕获,
  • 使用move关键字:获取所有权。

@IgorChubin 有点跟不上你在评论什么?你看到了之前的回答吗?我想我应该清理一下过时的评论。 - Andrey Tyukin

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接