“借来的价值活得不够久"使用构建器模式时 [英] "borrowed value does not live long enough" when using the builder pattern

查看:28
本文介绍了“借来的价值活得不够久"使用构建器模式时的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有以下代码:

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
    }
}

我希望能够做到这一点:

I would like to be able to do this:

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

我收到此错误:

错误:借来的价值活得不够长让 mut canvas = Canvas::new(100, 100, &renderer)

error: borrowed value does not live long enough let mut canvas = Canvas::new(100, 100, &renderer)

为什么返回的 Canvas 对象存活时间不够长?如果我将结果存储在中间 let 中,那么它就可以工作;为什么?

Why does the returned Canvas object not live long enough? If I store the result in an intermediate let, then it works; why?

推荐答案

这是一个最小的复制:

#[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);
}

Rust 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

Rust 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 不允许你引用无效的东西.


The problem arises because you create a temporary variable (1), then pass the reference to that variable to the method (2), which returns the reference. At the end of the method chain, you are trying to return the reference and store it in the variable, but the reference points to a temporary item that has nowhere to live! Rust doesn't let you have a reference to something that's invalid.

问题的一部分在于这不是构建器模式,这只是一个使用链式方法调用修改自身的结构.一些解决方案:

Part of the problem is that this is not the Builder pattern, this is just a struct that modifies itself using chained method invocation. Some solutions:

  1. 存储临时"变量,在这种情况下,所有方法都只是之后发生的正常变异方法.
  2. 采用 self 而不是对 self 的引用(&self, &mut self),然后最终返回完整的结构体.
  3. 在链的末尾有一个 build 方法,它返回另一个独立的结构,而不是引用.
  1. Store the "temporary" variable, in which case all the methods are just normal mutation methods that happen afterward.
  2. Take in self instead of a reference to self (&self, &mut self) and then ultimately return the full struct.
  3. Have a build method at the end of the chain that returns another standalone struct, not a reference.

这篇关于“借来的价值活得不够久"使用构建器模式时的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆