Howdy all! I've been writing Rust for about 2 weeks and LOVING IT. I've read through the book and other things and have gotten through about 5k lines of code that are working with tests and all.
I'm running into a borrowing problem. I understand what's happening, and why it's failing, but I'm not sure the best approach to fix it. I'd bet its a larger design issue.
Basically, in a loop that's in a function, I build up a custom struct that requires a reference. I then add that type to a vector. But, when the loop goes out of scope, I lose a value that has been borrowed. Crash.
Here is a stripped down portion of the code in question. This produces the same error as my full (and convoluted) code.
struct Footprint<'a> {
points: &'a Vec<Point>,
angles: Angle<'a>,
lines: Line<'a>,
}
impl<'a> Footprint<'a> {
pub fn from(points: &Vec<Point>) -> Footprint {
Footprint {
points,
lines: Line {points: &points},
angles: Angle {points: &points},
}
}
}
struct Line<'a> {
points: &'a Vec<Point>
}
struct Angle<'a> {
points: &'a Vec<Point>
}
struct Point {
x: f32,
y: f32,
}
fn main() {
let given: Vec<Vec<f32>> = vec![
vec![0.0, 2.0],
vec![1.0, 3.0],
vec![4.0, 0.0],
];
let built = make_footprints(given);
}
fn make_footprints<'a>(coords: Vec<Vec<f32>>) -> Vec<Footprint<'a>> {
let mut points = vec![];
for coord in coords {
let point = Point {
x: coord[0],
y: coord[1],
};
points.push(point);
}
let footprint = Footprint::from(&points);
vec![footprint]
}
And the pertinent error is:
error[E0597]: points
does not live long enough
--> src/main.rs:37:38
|
37 | let footprint = Footprint::from(&points);
| ^^^^^^ borrowed value does not live long enough
38 | vec![footprint]
39 | }
| - borrowed value only lives until here
|
note: borrowed value must be valid for the lifetime 'a as defined on the function body at 26:20...
I get that the issue is I am creating points
points inside make_footprints()
, and then handing the reference to points
into Footprint
, which needs to live longer than the original points
. I feel one way to solve this would be for Footprint
not to take a reference, but for other reasons, I think it has to.
I have also played around with collect() and map(), but ran into the same issue.
What would be great is to move that reference into footprint, but I'm not sure how to do that.
I am sure I am misunderstanding and butchering the borrow checker. Can anyone provide some guidance? Thank you!