Hi, newbie here.
I started programming in Rust recently and I've been struggling for a bit trying to resolve this problem. Sorry if it was answered before but I couldn't find a general answer to this issue.
What I trying to understand is how to process some data in a function and return references to that data in Rust. For example - see the code below - there's a struct called World
that keeps a vector of Shape
structs. The function find
will return a vector to those Shape
structs that match certain criteria. In this case is y > 0
but it can be whatever.
This is the code:
struct Shape {
pub x: i64,
pub y: i64,
}
struct World {
shapes: Vec<Shape>
}
impl World {
pub fn find_<'a>(self) -> Vec<&'a Shape> {
let result : Vec<&Shape> = self.shapes.iter().filter(|s| s.y > 0).collect();
result
}
}
fn main() {
let s1 = Shape { x: 0, y: 0 };
let s2 = Shape { x: 0, y: -1};
let world = World { shapes: vec![s1, s2]};
let result = world.find();
for shape in result {
print!("x: {}, y: {}", shape.x, shape.y);
}
}
It fails with the error:
bin/borrow.rs:13:9
|
12 | let result : Vec<&Shape> = self.shapes.iter().filter(|s| s.y > 0).collect();
| ----------- `self.shapes` is borrowed here
13 | result
| ^^^^^^ returns a value referencing data owned by the current function
I think I understand why this happens (the references created by the iterator will be deleted when the function is exited) but I'm not sure how to resolve this in Rust for a general case. Another scenario could be when you have a struct that is a graph and you want to find the shortest path to one node to another. You might want a vector that contains the nodes that compose that path.
Although this can work copying the structs instead of having references, I'd like to know if this makes sense in Rust. I'm thinking that it can be useful when there are complex structs that can store tons of data, when the expected result can be large (e.g, a path composed by thousands of nodes), or when working with threading or async where the state of the structs can me modified by several actors.
Thanks for your help!