我是使用rust 的新手,并且正为生命周期和容器对象而苦苦挣扎。我创建了一个基本的 list 类,用户可以在其中添加/删除/获取项目。我希望库存拥有该 Material 的所有权,并允许其他对象借用该 Material 。我为此一直苦苦挣扎,并且我已经读了一辈子了。大多数示例都非常简单,与此不同。我该如何退还该物品作为可变引用?
pub trait Item {
fn get_name(&self) -> String;
fn get_description(&self) -> String;
}
pub struct Inventory {
items: Vec<Box<dyn Item>>
}
impl Inventory {
pub fn new(&self) -> Inventory {
Inventory {
items: Vec::new()
}
}
pub fn add(&mut self, item: Box<dyn Item>) -> bool {
true
}
pub fn remove(&mut self, item: Box<dyn Item>) -> bool {
true
}
pub fn get(&self, index: usize) -> Option<Box<dyn Item>> {
return self.items.get(index)
}
}
最佳答案
pub fn get(&self, index: usize) -> Option<Box<dyn Item>> { ...
如果成功实现,则意味着get
正在移动或复制该项目,而不返回对它的引用-没有&
,因此调用者将获得所有权。您要用来借用的类型是:pub fn get(&self, index: usize) -> Option<&Box<dyn Item>> { ...
&
在Option<...>
内,因为Option
是专门为该查找创建的;它在Box<...>
之外,因为该框已经存在,这就是您要使用此方法借用的内容。可变的版本是:
pub fn get_mut(&mut self, index: usize) -> Option<&mut Box<dyn Item>> {
将所有内容放到将要编译的代码版本中:impl Inventory {
pub fn new(&self) -> Inventory {
Inventory {
items: Vec::new()
}
}
pub fn add(&mut self, item: Box<dyn Item>) -> bool {
self.items.push(item);
true
}
pub fn get(&self, index: usize) -> Option<&Box<dyn Item>> {
self.items.get(index)
}
pub fn get_mut(&mut self, index: usize) -> Option<&mut Box<dyn Item>> {
self.items.get_mut(index)
}
}
差不多是Vec
的包装器。我省略了
remove
,因为它实现起来比较复杂,但是请注意,如果您使用与remove
相同的参数编写add
,那么您将传入另一个新对象以让Inventory
拥有所有权,这可能不是最好的一种表示删除可变对象的方法,因为您需要制作第二个副本才能以零个副本结束,并且还需要定义Item
之间的相等性。而且,您不能使用
fn remove(&mut self, item: &Box<dyn Item>)
,因为那意味着要同时引用self
和self
的一部分,这是一个可变的引用,这是被禁止的。一些替代方法是通过名称,索引,过滤项目(例如
drain_filter
)来删除,或者甚至在可变的Item
中设置一个标志,指示在下一个方便时间(例如,下一次要删除项目)将其删除。添加)。也许应该有一个更好的主意。我本人对Rust还是很陌生。但是最有可能的是,最佳选择取决于需求-
Inventory
实际上需要具备的能力。
关于rust - 矢量对象的生命周期,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63387112/