Are these lines equivalent?
let ref mut a : [i32; 100]= [10;100];
let ref mut a : &mut[i32; 100]= &mut[10;100];
If yes why? And if no, what does it change?
In general, we say that « using ref
on the left side of a binding is equivalent to using &
on the right side ».
The type of your first a
is &mut [i32; 100]
; an exclusive reference to an (anonymous) array.
The type of your second a
is &mut &mut [i32; 100]
; an exclusive reference to an (anonymous) exclusive reference to an (anonymous) array.
You can easily display the type of an expression by causing an error with let () = ...
as in the example below (of course your source code editor can also help you when hovering a binding with the mouse).
In the example below, a1
can be used to alter the content of the (anonymous) array this exclusive reference points to.
a2
represents an additional level of indirection; we can make it forget the original information it pointed to, by reassigning to another information of the same type.
fn main() {
let ref mut a1: [i32; 5] = [1; 5];
// let () = a1; // this expression has type `&mut [i32; 5]`
// a1 •~~~> [1, 1, 1, 1, 1]
let ref mut a2: &mut [i32; 5] = &mut [2; 5];
// let () = a2; // this expression has type `&mut &mut [i32; 5]`
// a2 •~~~> (&mut [i32; 5]) •~~~> [2, 2, 2, 2, 2]
println!("before using a1: {:?}", a1);
a1[0] = 3;
println!("after using a1: {:?}", a1);
println!("before using a2: {:?}", a2);
*a2 = a1;
println!("after using a2: {:?}", a2);
}
before using a1: [1, 1, 1, 1, 1]
after using a1: [3, 1, 1, 1, 1]
before using a2: [2, 2, 2, 2, 2]
after using a2: [3, 1, 1, 1, 1]