Reputation: 1732
I'm trying to compile this code. The function get_lines
must generate a vector of Line
s, push a new line to it and return this vector.
fn main() {
let begin_point = Point{x:100, y:100};
let end_point = Point{x:300, y:100};
let lines = get_lines( &begin_point, &end_point);
}
fn get_lines<'a>(begin_point: &'a Point, end_point: &'a Point) -> Vec<Line<'a>>
{
let mut lines: Vec<Line> = vec![];
let middle_color = Color{r:0,g:0,b:0};
let line = Line {
begin_point: begin_point,
end_point: end_point,
color: &middle_color,
};
lines.push(line);
lines
}
struct Color<> {r:i32, g:i32, b:i32}
struct Point {x:i32, y:i32}
struct Line<'a> {
begin_point: &'a Point,
end_point: &'a Point,
color: &'a Color
}
Compilation fails with this error:
src\main.rs:16:17: 16:29 error: `middle_color` does not live long enough
src\main.rs:16 color: &middle_color,
^~~~~~~~~~~~
src\main.rs:9:1: 21:2 note: reference must be valid for the lifetime 'a as defined on the block at 9:0...
src\main.rs: 9 {
src\main.rs:10 let mut lines: Vec<Line> = vec![];
src\main.rs:11 let middle_color = Color{r:0,g:0,b:0};
src\main.rs:12
src\main.rs:13 let line = Line {
src\main.rs:14 begin_point: begin_point,
...
src\main.rs:11:43: 21:2 note: ...but borrowed value is only valid for the block suffix following statement 1 at 11:42
src\main.rs:11 let middle_color = Color{r:0,g:0,b:0};
src\main.rs:12
src\main.rs:13 let line = Line {
src\main.rs:14 begin_point: begin_point,
src\main.rs:15 end_point: end_point,
src\main.rs:16 color: &middle_color,
...
error: aborting due to previous error
How can I set the lifetime for a reference which isn't an argument of the function? Or is the logic of code wrong?
Upvotes: 3
Views: 158
Reputation: 1280
You get the error, because when get_lines()
returns, middle_color
goes out of scope and gets freed. You'd get a dangling pointer in the vector if this doesn't happen.
If you really want to use a reference in Line
to color
, you can instantiate it in the main
function and pass a reference to it into get_lines()
, e.g:
fn get_lines<'a>(begin_point: &'a Point, end_point: &'a Point, middle_color: &'a Color) -> Vec<Line<'a>>
{
...
}
But if you do this, you can even create your Line
in main
and move that into get_lines()
.
Upvotes: 3