rust - 在 Rust 闭包中重用绑定(bind)

标签 rust closures borrow-checker borrowing

我正在尝试生成 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 被移动到元组中,然后 尝试借用它来形成第二个元素。最简单的解决方案是做与此处相同的事情:交换元组元素的顺序。

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

Playground link

注意如果您想保留顺序:

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

关于rust - 在 Rust 闭包中重用绑定(bind),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40814832/

相关文章:

c# - 访问修改后的闭包,这是 ReSharper 错误吗?

xcode - 闭包中的 inout 参数使 Swift 编译器崩溃

rust - 与(表面上)似乎完全安全的短暂生命周期值相混淆

rust - Ref::map 内部符合人体工学的选项处理

rust - 为什么 rust 的 read_line 函数使用可变引用而不是返回值?

objective-c - 将 Swift block 转换为 Objective-C block

rust - 在 Rust 中返回一个引用和被引用的对象

rust - Mutex 中的可变借用失败

rust - 即使let语句之后,值仍然包裹在Option中

rust - 如何修复错误 "the trait ` OutputType` 未针对 `time::OffsetDateTime` 实现”?