consider this code, borrowed from this chapter from the official tutorial
fn main() {
let a = [1, 2, 3, 4, 5];
let b = [1, 2, 3, 4, 5];
let slice = &a[1..3];
let slice2 = &b[1..3];
assert_eq!(slice, &[2, 3]);
assert_eq!(slice2, &[2, 3]);
assert_eq!(slice, slice2);
}
I would expect the assertions to fail. Why every reference points to the same memory? At first I thought that's because a
and b
and the subsequent slices are immutable, so multiple references can address the same memory without problems. But:
fn main(){
let a = [1, 2, 3, 4, 5];
let mut b = [1, 2, 3, 4, 5];
let slice = &a[1..3];
let slice2 = &mut b[1..3];
slice2[0] = 2;
assert_eq!(slice, &[2, 3]);
assert_eq!(slice2, &[2, 3]);
assert_eq!(slice, slice2);
}
Again no assertion fails, this time if I change one slice I definitely want two different references, one to the changed slice and one to the immutable one.
However if I replace slice2[0] = 2;
with slice2[0] = 6;
(hence actually changing the slice) the assertions fail as expected. The possible causes I can imagine:
- assert_eq! is comparing the actual values not the references. I couldn't verify this since printing the value of a reference right now is above my skill set; the documentation mentions that it uses PartialEq and I don't know how it is implemented for references
- everything is done in a lazy fashion: only when and if one slice actually changes the new memory is allocated and the reference updated (the copy-on-write pattern)
Is this behavior documented somewhere?