2016-11-26 63 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