3

私は Rust を学んでいて、借用チェッカーと戦っています。

私は基本的なPoint構造を持っています。scaleポイントのすべての座標を変更する関数があります。という名前の別のメソッドからこのメソッドを呼び出したいconvert:

struct AngleUnit;

struct Point {
    x: f32,
    y: f32,
    z: f32,
    unit: AngleUnit,
}

fn factor(_from: AngleUnit, _to: AngleUnit) -> f32 {
    1.0
}

impl Point {
    pub fn new(x: f32, y: f32, z: f32, unit: AngleUnit) -> Point {
        Point { x, y, z, unit }
    }

    fn scale(&mut self, factor: f32) {
        self.x *= factor;
        self.y *= factor;
        self.z *= factor;
    }

    fn convert(&mut self, unit: AngleUnit) {
        let point_unit = self.unit;
        self.scale(factor(point_unit, unit));
    }
}

今、私は次のエラーがあります:

cannot move out of borrowed content

私は何を間違っていますか?

4

3 に答える 3

9

完全なエラー メッセージには次のように記載されています。

error[E0507]: cannot move out of borrowed content
  --> src/lib.rs:26:26
   |
26 |         let point_unit = self.unit;
   |                          ^^^^^^^^^
   |                          |
   |                          cannot move out of borrowed content
   |                          help: consider borrowing here: `&self.unit`

これは、移動が発生している場所を理解するのに役立ちます。

最も簡単なCopy解決策は、またはタイプのいずれかCloneを実装することAngleUnitです。の場合Copy、コードはそのまま機能します。のみの場合は、複製を作成するためCloneに明示的に呼び出す必要があります。.clone()

型を作成できない場合はCopy、コンパイラが提案するように、参照を使用できます。

fn factor(_from: &AngleUnit, _to: &AngleUnit) -> f32 {
    1.0
}
fn convert(&mut self, unit: AngleUnit) {
    let point_unit = &self.unit;
    self.scale(factor(point_unit, &unit));
}

元の問題はすべて次の行に要約されます。

let point_unit = self.unit;

の値はどうあるべきpoint_unitですか?

値を から に移動するとの値はどうなるでしょうか? 「簡単な」解決策は、それが未定義のメモリであることですが、経験上、私たちプログラマーはそれを台無しにして、デバッグするのにエキサイティングな問題を引き起こすことが示されています。self.unitpoint_unitself.unit

AngleUnit値を自動的にコピーすることはできますが、10 MiB のスペースを占有するタイプの場合はどうなるでしょうか? それから、無邪気に見える行が、たくさんの記憶と時間を吸い取った. それもあまりよろしくない。

代わりに、Rust は、型がデフォルトで移動され、オブジェクトを未定義の状態のままにしておくことができないようにします。特定のタイプは、自動的にコピーされる機能を選択できます — これがCopy特性です。タイプを明示的にコピーできるようにすることもできます —Cloneトレイト。既存の値への参照を取得して、それを渡すこともできます。借用チェッカーは、その参照が無効になった後にその参照を使用できないようにします。

于 2016-01-05T22:24:07.260 に答える
2

あなたは次の場所に移動self.unitしています:

let point_unit = self.unit;

参照を使用するか、タイプを作成してみてくださいCopy

于 2016-01-05T22:04:44.540 に答える