rust - 矢量对象的生命周期

标签 rust

我是使用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>),因为那意味着要同时引用selfself的一部分,这是一个可变的引用,这是被禁止的。
一些替代方法是通过名称,索引,过滤项目(例如 drain_filter )来删除,或者甚至在可变的Item中设置一个标志,指示在下一个方便时间(例如,下一次要删除项目)将其删除。添加)。
也许应该有一个更好的主意。我本人对Rust还是很陌生。但是最有可能的是,最佳选择取决于需求-Inventory实际上需要具备的能力。

关于rust - 矢量对象的生命周期,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63387112/

相关文章:

rust - Tokio 文档 "chaining computations"部分的示例无法编译: "expected struct ` std::io::Error`, found ()"

Rust 模块,结合两个 use 语句

rust - 在结构中引用内存的正确方法是什么

regex - 如何在没有积极前瞻的情况下重写正则表达式?

memory-management - 发生运行时 panic 时,堆栈/堆分配的类型会发生什么情况?

rust - 如何为Tree <T>实现IntoIterator?

rust - 有没有一种稳定的方法来告诉 Rustfmt 跳过整个文件

rust - 需要使用模块名称两次来引用模块中的结构

rust - 尝试从 GTK-RS 应用程序的事件处理程序中添加到 `gtk::ListBox` 时似乎没有任何反应

rust - 为什么不安全的代码可以编译,但推送到向量的类似代码会提示引用的生命周期不够长?