-1

Is there any difference between arr1 and arr2?

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

I know that the type of arr1 is [i32, 3] and &[i32, 3] for arr2. I understand this situation:

let arr1 = [1, 2, 3];

and this one:

let refer = &arr1;

Is there a reason to use &[data] instead of just [data]?

Shepmaster
  • 388,571
  • 95
  • 1,107
  • 1,366
Jakub Padło
  • 703
  • 3
  • 8
  • 16
  • 1
    Have you read [*The Rust Programming Language*](https://doc.rust-lang.org/book/)? It talks about why you'd want references vs values, and the same logic is true for arrays. – Shepmaster Feb 24 '20 at 16:22
  • I read this book. I understand what references are. I know why to give references to some variable / object. But why give references to the data block "inscribed in the code". I mean for example this: &[1, 2, 3]. – Jakub Padło Feb 24 '20 at 16:48
  • 1
    You state *I know why to give references to some variable / object* — **that's why** you can/would take a reference to a literal — because you need a reference. Perhaps your question is answered by [Why is it legal to borrow a temporary?](https://stackoverflow.com/q/47662253/155423) – Shepmaster Feb 24 '20 at 17:10
  • Thank you for link! – Jakub Padło Feb 24 '20 at 17:15

1 Answers1

1

First, when using an array ([i32]) and assigning it, you are actually creating a new copy of the array. When borrowing you are referencing the original value. In your example you are only using immutable values, so functionally there is not a difference between using arrays and borrowing but if you add mutability you can demonstrate this:

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]'

Second, Rust requires that function parameters have a defined size. Because arrays passed by value could be any size, you cannot pass arrays by value without first defining the size of the array in the function definition.

fn foo(val: [i32]) { // compile-time error

}
fn bar(val: [i32; 3]) { // allowed

}

However, &[i32] can be passed to a function because slices have a constant size. This allows you to write functions for arrays of any length rather than one specific size. Furthermore &[i32] is a more general type. If you have [i32] you can always create a &[i32], but you cannot create a [i32] from &[i32] without first copying the values.

fn foo(val: &[i32]) { // also allowed because &[i32] has a fixed size
   // some stuff
}
Cyber Ghost
  • 58
  • 1
  • 4
  • @JakubPadło [Why can I return a reference to a local literal but not a variable?](https://stackoverflow.com/q/50345139/155423) – Shepmaster Feb 24 '20 at 20:08