Hey there. I'm still learning Rust, and what I'm trying to accomplish is fairly simple (I think).
Imagine we had two structs: ItemManager and Item
struct ItemManager {
items: Vec<Item>,
}
impl ItemManager {
fn add(&mut self, item: Item) {
self.items.push(item);
}
}
struct Item {
id: u64,
desc: String,
}
impl Item{
fn new(id: u64, desc: String, manager: &mut ItemManager) -> Self {
let item = Self {
id,
desc,
};
// Uncomment the line below to make the compiler very angry:
// manager.add(item);
item
}
}
}
I know where the error is coming from: I'm moving the value item, and then I'm trying to return it. I know there must be an easy way to accomplish this, maybe using references, but I don't exactly know how.
Another question: I don't know if it's "Idiomatic Rust" to pass ItemManager to the "new" method of "Item".
I mean, I don't know if adding things to the manager should be a side-effect of calling "new" on a new item. Should I be passing the ItemManager as an argument, or is this not a good practice?
Thank you and apologies if this has an easy answer.
I think you'd have to get the item from items after pushing it there, as Vec doesn't currently offer any way to push and get a reference to the pushed object in one function as far as I know. It does feel a bit clunky though.
You have to return a reference because ItemManager owns the Item, if you wanted to return an owned Item you'd have to take it out of the Vec you just put it in.
I do think passing ItemManager to Item::new looks strange, even more so if you change it to return a reference. Personally I'd rather make it a method of ItemManager.
Depending on what ItemManager does with the items it’s managing, some combination of Arc/Rc/Weak might also be appropriate. For example, if ItemManager needs access to all the Items, but doesn’t need to keep them alive, you can do this:
Thank you all for your answers! I think that, at least for my own problem, the solution is to return a reference from Item as Heliozoa suggested.
Alice's heads up is also very insightful; I think I should make the manager parameter a reference (not a mutable reference).
As for 2e71828: Arc/Rc/Weak are some advanced terms I haven't gotten into yet! But I will re-read your answer as soon as I get there. I'm sure it makes a lot of sense. Thank you, too