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が、参照を保存しようとすると、有効期間に関するエラーが発生します。

4

1 に答える 1

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

ここで注意すべき重要なことは、順序が重要であるということです。distance_to借用によって呼び出すことができる行を交換するxと、借用は終了し、次に xに移動できますy

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

あなたの場合、タプルを構築するときに非常によく似たことが起こっています。pointタプルに移動され、それを借用して 2 番目の要素を形成しようとします。最も簡単な解決策は、ここと同じことを行うことです: タプルの要素の順序を入れ替えます。

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

遊び場リンク

注:注文を保持したい場合:

.map(|(a, b)| (b, a))
于 2016-11-26T11:13:50.053 に答える