在 Rust 闭包中重用绑定

Reuse binding in Rust closure

我正在尝试生成 Vec<(Point, f64)>:

let grid_size = 5;

let points_in_grid = (0..grid_size).flat_map(|x| {
    (0..grid_size)
        .map(|y| Point::new(f64::from(x), f64::from(y)))
        .collect::<Vec<Point>>()
});

let origin = Point::origin();

let points_and_distances = points_in_grid
    .map(|point| (point, point.distance_to(&origin)))
    .collect::<Vec<(Point, f64)>>();

我收到以下错误:

use of moved value: point

我知道我不能在元组的两个元素中都使用 point,但是当我尝试存储引用时,我收到有关生命周期的错误。

我假设您的 Point 结构如下所示:

#[derive(Debug)]
struct Point(f64, f64);

impl Point {
    fn new(x: f64, y: f64) -> Self { Point(x, y) }
    fn origin() -> Self { Point(0.,0.) }
    fn distance_to(&self, other: &Point) -> f64 {
        ((other.0 - self.0).powi(2) + (other.1 - self.1).powi(2)).sqrt()
    }
}

现在让我们看一个更简单的无法编译的例子:

let x = Point::new(2.5, 1.0);
let y = x;
let d = x.distance_to(&y);

给出错误:

error[E0382]: use of moved value: `x`
  --> <anon>:15:13
   |
14 |     let y = x;
   |         - value moved here
15 |     let d = x.distance_to(&y);
   |             ^ value used here after move
   |
   = note: move occurs because `x` has type `Point`, which does not implement the `Copy` trait

因为 x 已经移到 y 中,所以现在无法引用以调用 distance_to 函数。

这里要注意的重要一点是顺序很重要——如果我们交换行,我们可以通过借用 x 来调用 distance_to,借用将结束,然后 然后 x 可以移动到 y.

let x = Point(0., 0.);
let d = x.distance_to(&y);
let y = x; // compiles

在你的例子中,构造元组时发生了非常相似的事情。 point 被移动到元组中,然后 then 试图借用它来形成第二个元素。最简单的解决方案是做与此处相同的事情:交换元组元素的顺序。

let points_and_distances = points_in_grid
    .map(|point| (point.distance_to(&origin), point))
    .collect::<Vec<(f64, Point)>>(); // compiles

Playground link

N.B。如果您想保留订单:

.map(|(a, b)| (b, a))