Rust 在其他结构中存储结构的引用

Rust 在其他结构中存储结构的引用,rust,Rust,我有两个结构应用程序和项目 我想要实现的是通过将可变引用传递给项s构造函数,将项存储在App结构的项向量中 pub-struct应用程序 } 恳求{ pub fn new()->应用程序项{ 让项目=项目; 应用程序。注册项目(&项目); 项目 } } fn main(){ 让mut-app=app::new(); let item=item::新建(&mut应用程序);; } 代码显示以下错误: test.rs:8:28: 8:32 error: `item` does not live l

我有两个结构<代码>应用程序和
项目

我想要实现的是通过将可变引用传递给
s构造函数,将
存储在
App
结构的
向量中

pub-struct应用程序
}
恳求{
pub fn new()->应用程序项{
让项目=项目;
应用程序。注册项目(&项目);
项目
}
}
fn main(){
让mut-app=app::new();
let item=item::新建(&mut应用程序);;
}
代码显示以下错误:

test.rs:8:28: 8:32 error: `item` does not live long enough
test.rs:8         app.register_item(&item);

有什么方法可以做到这一点吗?

简单的解决方法是使用
Rc

use std::rc::Rc;

pub struct Item;

impl Item {

    pub fn new(app: &mut App) -> Rc<Item> {
        let item = Rc::new(Item);
        app.register_item(item.clone());
        item
    }

}

pub struct App {
    items: Vec<Rc<Item>>
}

...
使用std::rc::rc;
发布结构项;
impl项目{
发布fn新(应用程序:&mut应用程序)->Rc{
let item=Rc::新建(item);
app.register_项(item.clone());
项目
}
}
发布结构应用程序{
项目:Vec
}
...

虽然
Rc
对于您的用例来说可能是正确的,但最好理解为什么会出现错误。请阅读,因为它有一个关于为什么您的代码不能按原样工作的更深入的讨论。下面是一个简单的解释

让我们看看您的构造函数:

fn new(app: &mut App) -> Item {
    let item = Item;
    app.register_item(&item);
    item
}
在这里,我们在堆栈上的某个地址创建一个新的
。让我们假设地址是0x1000。然后,我们获取
项目的地址(0x1000),并将其存储到
应用程序中的
Vec
。然后,我们将
item
返回到调用函数,该函数位于不同的堆栈框架中。这意味着
的地址将更改,这意味着0x1000不再保证指向有效的
!这就是锈迹如何防止您产生所有类型的内存错误

我想说的是,你通常会看到这样写的:

fn main() {
    let item = Item;
    let mut app = App::new();
    app.register_item(&item);
}
如果您试图从此函数返回
app
item
,则会出现相同的问题,因为地址将更改


如果您有一个直接的树结构,我主张让父节点拥有子节点:

struct App {
    items: Vec<Item>
}

impl App {
    fn new() -> App {
        App { items: Vec::new() }
    }

    fn register_item(&mut self, item: Item) {
        self.items.push(item);
    }
}

pub struct Item;

fn main() {
    let mut app = App::new();
    app.register_item(Item);
}
struct应用程序{
项目:Vec
}
impl应用程序{
fn new()->App{
App{items:Vec::new()}
}
fn寄存器\项目(&mut self,项目:项目){
self.items.push(项目);
}
}
发布结构项;
fn main(){
让mut-app=app::new();
申请登记项目(项目);
}

除了立即出现的错误之外,这已经有了答案,在Vec中存储指针似乎是错误的。几乎可以肯定的是,在
App
中需要一个
Vec