gpt4 book ai didi

实现 drop 特性后 rust drop 调用序列

转载 作者:行者123 更新时间:2023-12-05 05:32:15 28 4
gpt4 key购买 nike

我是使用rust 的新手。我的简单代码

struct Foo<'a>{
data : & 'a String,
}
fn test_foo(){
let s1:String = String::from("A");
let mut foo:Foo = Foo { data: & s1 };
let s2:String = String::from("B");
foo.data = & s2;
}

我的查询:如果我为 Foo 结构实现 Drop 特性

foo.data = & s2; 

开始出现编译错误:s2 生命周期不够长。这个错误对我来说很有意义。但是,如果我没有为 Foo 实现 Drop 特性,为什么我不会得到同样的错误

最佳答案

在 Rust 中,局部变量(来自相同作用域)的删除顺序与它们定义的顺序相反。

fn test_foo(){
let s1:String = String::from("A");
let mut foo:Foo = Foo { data: & s1 };
let s2:String = String::from("B");
foo.data = & s2;
}

我们在这里声明了三个局部变量:s1 , foo , 和 s2 , 以该顺序。 Rust 想以相反的顺序删除它们:s2首先,然后 foo , 然后 s1 .但是,生命周期存在问题。一旦我们放下s2 , 然后 foo.data 未初始化,即它指向垃圾内存。

现在,为什么没有 Drop 也能正常工作? ? Rust 有一个概念叫做 partial moves .如果你有一个包含多个字段的结构,Rust 将允许你移出一些字段而不会使整个结构失效。原则上,如果我有一个

struct Person {
name: String,
age: i32,
occupation: String,
}

我也是let name = my_person.name; (其中 my_person: Person ),然后我从 Person 中移出了一个值.因此,my_person.name无效,并且在没有部分移动的情况下,Rust 应该考虑 my_person完全无效。但是,我们知道 my_person.agemy_person.occupation仍然有效,所以 Rust 会让 ageoccupation留在原地。它记得 name被移动(因此不应丢弃垃圾),而 ageoccupation仍然有效。

在您的示例中,发生了同样的事情。 Rust 想要下降 s2 ,但是 Foo仍然持有对它的引用。 Rust 认为这很好:我们将删除 s2简单地说Foo已被部分移动:它的data字段不再有效。然后当我们去下降foo接下来,我们不需要删除引用,只需删除最外层的 Foo层本身。

没有 Drop例如,这很好,Rust 会允许它。但是,如果 impl<'a> Drop for Foo<'a>在范围内,则对于 Foo完全禁用部分移动. Rust 看到您正在实现一些自定义 Drop行为,现在它不允许存在部分初始化的对象,因为我们必须删除部分初始化的对象,而 Rust 无法预测您的自定义 Drop代码将要执行的操作或它将要做出的假设。

因此 Drop实现,Rust 仍然想放弃 s2首先,但它不能将引用部分移出 foo ,因为那会留下 foo处于部分初始化状态,这是不允许的。

关于实现 drop 特性后 rust drop 调用序列,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/74174650/

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