I'm solving a fairly classic "matchmaking" problem, commonly solved as an assignment-type problem in Operations Research. I have the following structs represent a Person
and a Compatibility
between two people.
struct Person {
name: String,
}
struct Compatibility<'a> {
lhs: &'a Person,
rhs: &'a Person,
compatibility_score: f64,
}
This is fine. Compatibilities don't own the persons they represent in their fields and as such just store references to them, but they must live at least as long as them, hence the lifetime param. I can easily create some objects of both types like this:
fn create_model() {
let persons = vec![
Person{name: "Katie".to_string()},
Person{name: "Helen".to_string()},
];
let compatibilities = vec![
Compatibility{lhs: &persons[0], rhs: &persons[1], compatibility_score: 50.0},
];
}
I'm trying to introduce a third struct, Model
, which will own a vector of Person
as well as a vector of Compatibility
, and as such represent the data model which the problem will be run on.
pub struct Model {
persons: Vec<Person>,
compatibilities: Vec<Compatibility>,
}
Now this won't compile because Compatibility
speficies a lifetime parameter, and so it seems that even though Model
will own a vector of Compatibility
, it still needs to specify a lifetime parameter, or otherwise we'll end up with error[E0106]: missing lifetime specifier
. This makes some kind of sense to me - I mean, if an instance of Compatibility
needs to live for at least as long as the Person
instances it references, then the compiler needs to ensure that anything which owns a compatibility also lives as long. So I add that in like so:
pub struct Model<'a> {
persons: Vec<Person>,
compatibilities: Vec<Compatibility<'a>>,
}
This is now building. But now how do I actually create a Model
? Continuing from the earlier snippet, if I try to do this:
Model {
persons,
compatibilities
}
Then the compiler complains that I am moving persons
, but it is still being borrowed by compatibilities
. The thing is, I know it's still being borrowed by compatibilities, and I'm trying to move both of them into the Model
instance. I need to somehow connect the two vectors so the compiler understands they live together.
Code is on playground if you'd like to edit it yourself.