References and move vs. copy
Solution 1:
fn main() { let s1 = String::from("Hello"); let s2 = &s1; do_something(s2); println!("{}", s2); }
This works because references are Copy
. s2
is copied, not moved, and can continue to be used after the call to do_something
.
Is the above the same as this?
fn main() { let a = 5; let b = &a; do_something(b); println!("{}", b); }
Yes, it is. It doesn't matter if a
or s1
are Copy
, only that b
or s2
are.
I guess my question is, are they
Copy
because they are always pointers to stack-allocated data?
All shared references are Copy
because of the blanket implementation:
impl<'_, T> Copy for &'_ T where T: ?Sized,
It doesn't matter where the references point, stack or heap or .data
section or anywhere else. References are small word-sized values and it's convenient and efficient to copy them, so Rust makes them Copy
.
That's the usual metric: Is copying efficient? String
s aren't Copy
because cloning them is an expensive O(n) operation. &str
s, being references, are Copy
because copying pointers is cheap.
(It's not the only metric, of course. Some types are not Copy
because they are logically unique. For example, Box
is also just a pointer, but it's an owned type, not a shared reference.)