在 Rust 中,与普通结构相比,Box:ed 结构的删除顺序是否有差异?

Mar*_*son 2 scope lifetime rust

以下代码无法编译:

struct Ref<'a> {
    nbr: &'a u32,
}

fn func<'a>() {
    let nbr: u32 = 42;
    let _a_ref: Box<Ref<'a>> = Box::new(Ref { nbr: &nbr });
}

fn main() {
    func();
}
Run Code Online (Sandbox Code Playgroud)

编译器抱怨说'nbr' does not live long enough,它在仍然借用的末尾被删除func()。我基本上到处都搜索过,但我不明白为什么会出现这个错误。与声明相比,变量应该以相反的顺序删除,因此包含Ref引用的框应该在nbr删除之前删除,对吗?

如果我改成func()

fn func<'a>() {
    let nbr: u32 = 42;
    let _a_ref = Ref { nbr: &nbr };
}
Run Code Online (Sandbox Code Playgroud)

它构建得很好!因此,盒装参考所需的生命周期/范围存在一些差异 - 但我找不到对这个明显基本问题的任何清晰和简单的解释。

_a_ref为了让它更加混乱,我注意到如果我声明这样的类型:

fn func<'a>() {
    let nbr: u32 = 42;
    let _a_ref: Ref<'a> = Ref { nbr: &nbr };
}
Run Code Online (Sandbox Code Playgroud)

我再次收到'nbr' does not live long enough错误。

最后,我使用了下划线,如下所示:

fn func<'a>() {
    let nbr: u32 = 42;
    let _a_ref: Ref<'_> = Ref { nbr: &nbr };
}
Run Code Online (Sandbox Code Playgroud)

现在它又恢复正常了!这 3 种使用非装箱结构的方式有什么区别Ref?它们与盒装版本相比如何?

Cha*_*man 5

Box不是这里的问题,'a是。

&nbr的寿命为nbr. But'a是调用者选择的生命周期,它可能(甚至总是)比 的生命周期长nbr。所以你不能分配Ref<'nbr>Ref<'a>.

Ref<'_>意思是“让编译器推断生命周期”,基本上相当于根本不指定类型。

  • “调用者选择”意味着无论谁调用`func`都可以选择`'a`。目前在 `main` 中调用它的方式,`'a` 在调用 `func` 之前开始,在它返回之后结束,这确实只是“稍微”太长了。但是没有什么可以阻止有人将其称为“func::&lt;'static&gt;()”,这需要引用永远存在。 (2认同)