Во-первых, при использовании массива ([i32]
) и его назначении вы фактически создаете новую копию массива. При заимствовании вы ссылаетесь на первоначальную стоимость. В вашем примере вы используете только неизменяемые значения, поэтому функционально нет никакой разницы между использованием массивов и заимствованием, но если вы добавите изменчивость, вы можете продемонстрировать это:
let mut array = [1, 2, 3];
let mut copy = array;
copy[0] = 10;
let borrow = &mut array;
borrow[1] = 20;
foo(array);
//print original
println!("array: {:?}", array); // Prints 'array: [1, 20, 3]'
//print copy
println!("copy: {:?}", copy); // Prints 'copy: [10, 2, 3]'
Во-вторых, Rust требует, чтобы параметры функции имели определенный размер. Поскольку массивы, передаваемые по значению, могут быть любого размера, вы не можете передавать массивы по значению без предварительного определения размера массива в определении функции.
fn foo(val: [i32]) { // compile-time error
}
fn bar(val: [i32; 3]) { // allowed
}
Однако &[i32]
можно передать в функцию, поскольку ломтики имеют постоянный размер. Это позволяет вам писать функции для массивов любой длины, а не одного указанного c размера. Кроме того, &[i32]
является более общим типом. Если у вас есть [i32]
, вы всегда можете создать &[i32]
, но вы не можете создать [i32]
из &[i32]
без предварительного копирования значений.
fn foo(val: &[i32]) { // also allowed because &[i32] has a fixed size
// some stuff
}