以下代码无法编译:

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

编译器抱怨它是'nbr' does not live long enough,并且它在func()的末尾被丢弃,而它仍然被borrow .我基本上到处都找过了,但我不明白为什么会发生这个错误.与声明相比,变量应该以相反的顺序被删除,所以包含引用的方框Ref应该在nbr被删除之前被删除,对吗?

如果我把func()改成:

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

它建造得很好!因此,盒装引用所需的生存期/范围有一些不同--但我找不到对这个明显基本的问题的任何明确和简单的解释.

更令人困惑的是,我注意到,如果我这样描述_a_ref的类型:

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

我又犯了'nbr' does not live long enough个错误.

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

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

现在,它又建造得很好了!这三种使用非盒装Ref struct 的方法有什么不同?它们与盒装变种相比又如何呢?

推荐答案

这里的问题不是Box,而是'a.

&nbr人的生命周期 是nbr岁.但'a是调用者 Select 的生存期,它可能(甚至始终会)大于nbr的生存期.因此,您不能将Ref<'nbr>赋给Ref<'a>.

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

Rust相关问答推荐

计算具有相邻调换且没有插入或删除的序列的距离

文档示例需要导入相关的 struct ,但仅在运行测试时.这是故意的行为吗?

异步FN中的 rust 递归

在执行其他工作的同时,从共享裁判后面的VEC中删除重复项

Trait bound i8:来自u8的不满意

如果死 struct 实现了/派生了一些特征,为什么Rust会停止检测它们?

如果变量本身不是None,如何返回;如果没有,则返回None&Quot;?

Rust将String上的迭代器转换为&;[&;str]

为什么我需要 to_string 函数的参考?

仅发布工作区的二进制 crate

如何处理闭包中的生命周期以及作为参数和返回类型的闭包?

需要哪些编译器优化来优化此递归调用?

.to_owned()、.clone() 和取消引用 (*) 之间有区别吗?

为什么不能在 Rust 中声明静态或常量 std::path::Path 对象?

如何在 Rust 中创建最后一个元素是可变长度数组的 struct ?

有没有办法阻止 rust-analyzer 使非活动代码变暗?

在 Rust 中枚举字符串的最佳方式? (字符()与 as_bytes())

覆盖类型的要求到底是什么?为什么单个元素元组满足它?

为什么-x试图解析为文字并在声明性宏中失败?

令人困惑的错误消息? (解包运算符)