为何向函数传参时Array需传引用,而Vector无需传引用?
Rust中数组与向量传递方式差异的原因
示例代码
fn _print_array(arr: &[i32]) { println!("Array : {:?}", arr); } pub fn print_array() { let _a:[i32;3]=[1,2,3]; _print_array(&_a); } fn _print_vector(v: Vec<i32>) { println!("Vector : {:?}", v); } pub fn print_vector() { let _v:Vec<i32> = vec![1, 2, 3]; _print_vector(_v); }
问题
在Rust中,为何将Array作为函数参数传递时需要使用引用,而传递Vector时却不需要?
解答
这个差异本质是由Rust中数组与向量的类型特性和所有权系统共同决定的:
数组的固定大小特性限制了直接传递的通用性
Rust的数组是栈上分配的固定长度类型,比如[i32;3]和[i32;4]是完全不同的类型。如果函数参数直接声明为[i32;3],那这个函数只能接收长度为3的i32数组,无法复用给其他长度的数组。而使用引用&[i32]实际上传递的是切片类型,切片可以指向任意长度的i32数组,同时还能避免栈上复制整个数组(如果数组元素很多,复制会带来明显性能开销)。向量支持所有权转移,move传递成本极低
Vector是堆分配的动态大小类型,它的内部只包含指向堆内存的指针、长度和容量这几个小字段。当你把Vector直接传递给函数(比如示例中的_print_vector(_v)),实际上是触发了所有权转移(move)——把_v的所有权转移给函数参数v,原来的_v在调用后就不能再使用了。这种move操作的成本极低,只是拷贝几个字节的元数据,不需要复制堆上的实际元素。注意:向量并不是“不需要”用引用传递,你完全可以选择传递
&Vec<i32>或者切片&[i32]来保留原变量的所有权,示例只是选择了move传递的方式而已。
内容的提问来源于stack exchange,提问作者user366312
相关产品推荐
相关产品推荐

