动态 – Rust中的所有权跟踪:Box(堆)和T(堆栈)之间的差异
发布时间:2020-12-15 04:49:07 所属栏目:Java 来源:网络整理
导读:尝试使用编程语言Rust,我发现编译器能够非常准确地跟踪堆栈中某些结构的字段的移动(它确切地知道哪个字段已移动). 但是,当我将结构的一部分放入Box(即将其放入堆中)时,编译器不再能够确定在取消引用该框之后发生的所有事件的字段级移动.它将假设“盒子内部”
尝试使用编程语言Rust,我发现编译器能够非常准确地跟踪堆栈中某些结构的字段的移动(它确切地知道哪个字段已移动).
但是,当我将结构的一部分放入Box(即将其放入堆中)时,编译器不再能够确定在取消引用该框之后发生的所有事件的字段级移动.它将假设“盒子内部”的整个结构已经移动.让我们首先看一下一切都在堆栈上的例子: struct OuterContainer { inner: InnerContainer } struct InnerContainer { val_a: ValContainer,val_b: ValContainer } struct ValContainer { i: i32 } fn main() { // Note that the whole structure lives on the stack. let structure = OuterContainer { inner: InnerContainer { val_a: ValContainer { i: 42 },val_b: ValContainer { i: 100 } } }; // Move just one field (val_a) of the inner container. let move_me = structure.inner.val_a; // We can still borrow the other field (val_b). let borrow_me = &structure.inner.val_b; } 现在是相同的例子但只有一个小改动:我们将InnerContainer放入一个盒子(Box< InnerContainer>). struct OuterContainer { inner: Box<InnerContainer> } struct InnerContainer { val_a: ValContainer,val_b: ValContainer } struct ValContainer { i: i32 } fn main() { // Note that the whole structure lives on the stack. let structure = OuterContainer { inner: Box::new(InnerContainer { val_a: ValContainer { i: 42 },val_b: ValContainer { i: 100 } }) }; // Move just one field (val_a) of the inner container. // Note that now,the inner container lives on the heap. let move_me = structure.inner.val_a; // We can no longer borrow the other field (val_b). let borrow_me = &structure.inner.val_b; // error: "value used after move" } 我怀疑它与堆栈的性质和堆的性质有关,前者是静态的(至少每个堆栈帧),而后者是动态的.也许编译器需要安全地使用它,因为我无法清楚地表达/识别. 解决方法
在摘要中,堆栈上的结构只是一个通用名称下的一堆变量.编译器知道这一点,并且可以将结构分解为一组独立的堆栈变量.这使它可以独立跟踪每个场的移动.
它不能用Box或任何其他类型的自定义分配,因为编译器不控制Box. Box只是标准库中的一些代码,而不是语言的固有部分. Box无法推断自身的不同部分突然变得无效.当摧毁Box时,它的Drop实现只知道要毁掉一切. 换句话说:在堆栈上,编译器处于完全控制状态,因此可以执行奇特的操作,例如破坏结构并逐个移动它们.一旦自定义分配进入图片,所有投注都会关闭,编译器必须退出并停止尝试变得聪明. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |