10

次のコードがあります。

pub struct Canvas<'a> {
    width: isize,
    height: isize,
    color: Color,
    surface: Surface,
    texture: Texture,
    renderer: &'a Renderer,
}

impl<'a> Canvas<'a> {
    pub fn new(width: isize, height: isize, renderer: &'a Renderer) -> Canvas<'a> {
        let color = Color::RGB(0, 30, 0);
        let mut surface = core::create_surface(width, height);
        let texture = Canvas::gen_texture(&mut surface, width, height, color, renderer);
        Canvas {
            width: width,
            height: height,
            color: color,
            surface: surface,
            texture: texture,
            renderer: renderer,
        }
    }

    pub fn color(&mut self, color: Color) -> &mut Canvas<'a> {
        self.color = color;
        self.texture = Canvas::gen_texture(
            &mut self.surface,
            self.width,
            self.height,
            self.color,
            self.renderer,
        );
        self
    }
}

私はこれを行うことができるようにしたいと思います:

let mut canvas = Canvas::new(100, 100, &renderer).color(Color::RGB(80, 230, 80));

次のエラーが表示されます。

エラー: 借用した値は長生きしません let mut canvas = Canvas::new(100, 100, &renderer)

Canvas返されたオブジェクトが十分に長く存続しないのはなぜですか? 結果を中間に保存すると、let機能します。なぜ?

4

1 に答える 1

17

最小限の複製を次に示します。

#[derive(Debug)]
pub struct Canvas;

impl Canvas {
    fn new() -> Self {
        Canvas
    }

    fn color(&self) -> &Canvas {
        self
    }
}

fn main() {
    let mut canvas = Canvas::new().color();
    //             1 ^~~~~~~~~~~~~
    //                           2 ^~~~~
    println!("{:?}", canvas);
}

さび 2015

error[E0597]: borrowed value does not live long enough
  --> src/main.rs:15:22
   |
15 |     let mut canvas = Canvas::new().color();
   |                      ^^^^^^^^^^^^^        - temporary value dropped here while still borrowed
   |                      |
   |                      temporary value does not live long enough
...
19 | }
   | - temporary value needs to live until here
   |
   = note: consider using a `let` binding to increase its lifetime

ラスト2018

error[E0716]: temporary value dropped while borrowed
  --> src/main.rs:15:22
   |
15 |     let mut canvas = Canvas::new().color();
   |                      ^^^^^^^^^^^^^        - temporary value is freed at the end of this statement
   |                      |
   |                      creates a temporary which is freed while still in use
...
18 |     println!("{:?}", canvas);
   |                      ------ borrow later used here
   |
   = note: consider using a `let` binding to create a longer lived value

問題が発生するのは、一時変数を作成し (1)、その変数への参照をメソッドに渡し (2)、メソッドが参照を返すためです。メソッド チェーンの最後で、参照を返して変数に格納しようとしていますが、参照は一時的なアイテムを指しており、存在する場所がありません。Rust では、無効なものへの参照を許可しません。

問題の一部は、これが Builder パターンではなく、チェーンされたメソッド呼び出しを使用して自身を変更する構造体にすぎないことです。いくつかの解決策:

  1. 「一時」変数を保存します。この場合、すべてのメソッドは、後で発生する通常のミューテーション メソッドです。
  2. selfself ( &self, ) への参照の代わりに&mut self取り込み、最終的に完全な構造体を返します。
  3. build参照ではなく、別のスタンドアロン構造体を返すメソッドをチェーンの最後に配置します。
于 2015-02-12T05:16:06.490 に答える