2016-11-26 62 views
1

结合我试图生成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,但是当我尝试存储引用时,我会遇到有关生存期的错误。

+0

你能否提供一个完整的可编译(即使有错误)的例子,最好是哪个可以在play.rust-lang.org上工作?确定你得到什么错误以及在哪里,并提出修复方案会更容易。 –

回答

1

我假设你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)) 
+1

换句话说,'Point'没有实现['Copy'](https://doc.rust-lang.org/std/marker/trait.Copy.html)。你也可以使用临时变量 - '.map(| point | {let d = point.distance_to(&origin);(point,d)})'。 – Shepmaster