Есть ли причина использовать & [data] вместо просто [data]? - PullRequest
0 голосов
/ 24 февраля 2020

Есть ли разница между arr1 и arr2?

let arr1 = [1, 2, 3];
let arr2 = &[1, 2, 3];

Я знаю, что тип arr1 равен [i32, 3] и &[i32, 3] для arr2. Я понимаю эту ситуацию:

let arr1 = [1, 2, 3];

и эту:

let refer = &arr1;

Есть ли причина использовать &[data] вместо просто [data]?

1 Ответ

1 голос
/ 24 февраля 2020

Во-первых, при использовании массива ([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
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...