在下面的示例中:
struct Foo {
a: [u64; 100000],
}
fn foo(mut f: Foo) -> Foo {
f.a[0] = 99999;
f.a[1] = 99999;
println!("{:?}", &mut f as *mut Foo);
for i in 0..f.a[0] {
f.a[i as usize] = 21444;
}
return f;
}
fn main(){
let mut f = Foo {
a:[0;100000]
};
println!("{:?}", &mut f as *mut Foo);
f = foo(f);
println!("{:?}", &mut f as *mut Foo);
}
我发现在传递到函数foo
前后,f
的地址是不同的。为什么Rust到处都会复制这么大的结构,却没有真正移动它(或实现此优化)?
我了解堆栈存储器的工作原理。但是利用Rust中所有权提供的信息,我认为可以避免复制。编译器不必要地复制了两次数组。这可以对Rust编译器进行优化吗?
答案 0 :(得分:4)
举动是一种记忆,其后将源视为不存在。
您的大数组在堆栈中。这就是Rust的内存模型的工作方式:局部变量在堆栈中。由于函数返回时foo
的堆栈空间将消失,因此编译器除了将内存复制到main
的堆栈空间之外,无能为力。
在某些情况下,编译器可以重新安排事情,以便消除移动(将源和目标合并为一件事),但这是不能依靠的优化,尤其是对于大事情。
如果您不想复制巨大的数组,请自己通过Box<[u64]>
或直接使用Vec<u64>
在堆上分配它。