Rust编译器如何知道值是否已移动?
一个简单的例子:Rust编译器如何知道值是否已移动?,rust,Rust,一个简单的例子: struct A; fn main() { test(2); test(1); } fn test(i: i32) { println!("test"); let a = A; if i == 2 { us(a); } println!("end"); } impl Drop for A { fn drop(&mut self) { println!("drop");
struct A;
fn main() {
test(2);
test(1);
}
fn test(i: i32) {
println!("test");
let a = A;
if i == 2 {
us(a);
}
println!("end");
}
impl Drop for A {
fn drop(&mut self) {
println!("drop");
}
}
#[allow(unused_variables)]
fn us(a: A){
println!("use");
}
当我运行它时,输出是:
test
use
drop
end
test
end
drop
我知道在test(2)
案例中,a
被移动到us(a)
,所以它的输出是“test-use-drop-end”
但是,在test(1)
中,输出是“testend drop”,这意味着编译器知道a
没有移动
如果调用了us(a)
,则无需在test(i)
中删除a
,它将在us(a)
中删除;如果未调用us(a)
,则必须在println之后删除a
!(“结束”)
既然编译器不可能知道是否调用了us(a)
,那么编译器如何知道在println之后是否应该调用a.drop()
!(“结束”)
?中对此进行了解释:
从Rust 1.0开始,drop标志实际上并没有秘密地隐藏在实现drop的任何类型的隐藏字段中
隐藏字段说明当前值是否已删除,如果未删除,则为删除。因此,这在运行时是已知的,并且需要一些簿记
展望未来,有一个RFC RFC的理念是通过以下方式替换隐藏字段:
- 主要优点是
现在将始终提供与C的表示等价的表示,即使#[repr(C)]
实现了struct
Drop
- 另一个重要的优点是节省内存(通过不膨胀
大小)struct
- 另一个微小的优势是,由于无条件丢弃和更好的缓存(通过减少内存大小),可能会略微提高速度