gpt4 book ai didi

rust - 在其他结构中存储结构的引用

转载 作者:行者123 更新时间:2023-11-29 07:57:47 26 4
gpt4 key购买 nike

我有两个结构。 AppItem .

我想要实现的是存储一个 Itemitems App 的矢量通过传递对 Item 的可变引用来构造s 构造函数。

pub struct App<'a> {
items: Vec<&'a Item>
}

impl<'a> App<'a> {
pub fn new() -> App<'a> {
App { items: Vec::new() }
}
pub fn register_item(&mut self, item: &'a Item) {
self.items.push(item);
}
}

pub struct Item;

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

fn main() {
let mut app = App::new();

let item = Item::new(&mut app);;
}

代码抛出以下错误:

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

有什么办法吗?

最佳答案

虽然 Rc 对于您的用例可能是正确的,但最好了解您为什么会收到错误。请阅读Why can't I store a value and a reference to that value in the same struct?因为它对为什么您的代码不能按原样工作进行了更深入的讨论。下面是一个简化的解释。

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

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

在这里,我们在堆栈中的某个地址创建了一个新的Item。让我们假设地址是 0x1000。然后我们获取 item 的地址 (0x1000) 并将其存储到 App 内的 Vec 中。然后我们将 item 返回给驻留在不同栈帧中的调用函数。这意味着 item 的地址将发生变化,这意味着 0x1000 不再保证指向有效的 Item!这就是 Rust 防止你犯下整类内存错误的方法!

我会说你通常会看到它写成:

fn main() {
let item = Item;
let mut app = App::new();
app.register_item(&item);
}

如果您尝试从此函数返回 appitem,则会遇到同样的问题,因为地址会改变。


如果你有一个直接的树结构,我提倡简单地让父节点拥有子节点:

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);
}

关于rust - 在其他结构中存储结构的引用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30538387/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com