繁体   English   中英

为什么Rust中的“移动”实际上并没有移动?

[英]Why does “move” in Rust not actually move?

在下面的例子中:

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编译器的优化吗?

移动是一个memcpy,然后将源视为不存在。

你的大阵列在堆栈上。 这就是Rust的内存模型的工作方式:局部变量在堆栈中。 由于foo的堆栈空间在函数返回时消失,除了将内存复制到main的堆栈空间之外,编译器无法做任何事情。

在某些情况下,编译器可以重新排列事物,以便可以省略移动(源和目标合并为一件事),但这是一种不能依赖的优化,尤其是对于大事物。

如果你不想复制庞大的数组,可以自己在堆上分配它,或者通过Box<[u64]> ,或者只是使用Vec<u64>

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM