Rust中数组执行move操作时会拷贝其内部元素吗?
问题解答
首先给出结论:该场景下数组从get_array()返回时,包含的元素会被拷贝。
对应的Rust代码如下:
fn get_array() -> [u8; 4] { let a = [0, 1, 2, 3]; let mut b = a; // 此处对a做move,因为数组是Copy类型,实际执行拷贝操作 b[2] = 10; a } fn main() { let a = get_array(); println!("{:?}", a); }
运行上述代码会输出[0, 1, 2, 3],也能佐证b是a的独立拷贝,修改b不会对a产生影响。
具体逻辑说明
- Rust中数组是栈上分配的固定长度集合,当数组的元素类型实现了
Copytrait时,整个数组类型也会自动实现Copy。本案例中元素是u8原生整数类型,天然实现了Copy,因此[u8;4]整体是Copy类型。 - Rust的所有
move操作本质都是对栈上的值做逐字节浅拷贝,区别仅在于:- 未实现
Copy的类型执行move后,原变量会被标记为失效,无法再访问 - 实现了
Copy的类型执行move后,原变量仍然可用,相当于隐式完成了一次拷贝
- 未实现
- 本案例中返回
a的操作属于move,因为[u8;4]是Copy类型,所以会把栈上存储的4个u8元素全部逐字节拷贝到main函数中对应变量的栈空间,也就是元素发生了拷贝。 - 补充验证:如果把数组类型换成非Copy的
[String;4],代码中let mut b = a;之后再返回a会直接编译报错,因为此时a已经被move给b,无法再次访问。这种非Copy数组返回时的move仍然会拷贝栈上存储的String元数据(指针、长度、容量),但不会拷贝String指向的堆上的字符串内容。
内容的提问来源于stack exchange,提问作者quentinadam
相关产品推荐
相关产品推荐

