I have the following code:
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));
I get this error:
error: borrowed value does not live long enough let mut canvas = Canvas::new(100, 100, &renderer)
Why does the returned Canvas
object not live long enough? If I store the result in an intermediate let
, then it works; why?
Here's a minimal reproduction:
Rust 2015
Rust 2018
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:
self
instead of a reference to self (&self
,&mut self
) and then ultimately return the full struct.build
method at the end of the chain that returns another standalone struct, not a reference.