提问人:Marcus Johansson 提问时间:11/10/2023 更新时间:11/10/2023 访问量:68
在 Rust 中,Box:ed 结构体与普通结构体相比,放置顺序有区别吗?
In Rust, is there a difference in drop order for a Box:ed struct compared to a plain struct?
问:
以下代码不编译:
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()
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 };
}
现在它又构建得很好!这 3 种使用非装箱结构的方法有什么区别?它们与盒装变体相比如何?Ref
答:
5赞
Chayim Friedman
11/10/2023
#1
这不是问题所在。Box
'a
&nbr
具有 的生存期。但是是调用方选择的生存期,它可能(甚至总是)大于 的生存期。因此,您不能分配给 .nbr
'a
nbr
Ref<'nbr>
Ref<'a>
Ref<'_>
表示“让编译器推断生存期”,基本上等同于根本不指定类型。
评论
0赞
Marcus Johansson
11/10/2023
我想我很难理解 Rust 中生命周期概念的确切含义以及编译器如何应用它。我非常了解范围,而且它是不一样的。当你说这将大于 的寿命时,这意味着什么?为什么 Box 变体不编译?'a
nbr
1赞
Jmb
11/10/2023
@MarcusJohansson 如果你使用 ,变体会编译,它不会编译,因为你告诉编译器使用 ,并且由于来自调用者,所以它比函数持续时间更长。Box
Box<Ref<'_>>
'a
'a
0赞
Marcus Johansson
11/10/2023
啊,所以“调用者选择”的意思是,作为调用者(甚至只是一个实例化结构并将其绑定到变量的函数),提供参考并提及生存期,我基本上将定义这个生存期以包括我的完整范围,它“略高于”我作为调用者范围内的所有变量?因此,即使在删除作用域中的最后一个变量之后,也要求 in 是有效的引用。但是,在实践中,使用允许编译器推断生存期会使应用的生存期更接近 ?a
&'a u32
Ref
Ref<'_>
nbr
2赞
Jmb
11/10/2023
“呼叫者选择”意味着呼叫者将选择。你目前调用它的方式,在被调用之前开始,在它返回后结束,这确实只是“稍微”太长了。但是没有什么能阻止有人称它为 ,这需要引用才能永生。func
'a
main
'a
func
func::<'static>()
评论