Copying and cloning
In Chapter 1, Hello Rust!, we discussed Send, a marker trait that allows a type to be "sent" across multiple threads. Something that's similar but less complex is local moving, which commonly occurs in a program—for example, when you pass a variable into a function.
Copying and cloning, on the other hand, happen on different occasions. When a variable is assigned to another variable, the compiler will typically copy the value implicitly, which can be done safely and cheaply for stack-allocated variables.
Cloning is always a deep copy of a type—implemented either manually (with the Clone trait) or by using the derive macro. Then, cloning is only a matter of invoking the clone() function, an operation that is not necessarily cheap. The following snippet illustrates these two operations:
let y = 5;
let x = y; // Copy
let a = Rc::new(5);
let b = a.clone(); // Clone
The regular usage of these traits and operations is usually intuitive and there isn't much that can go wrong. Usually the compiler clearly states the need for a Copy implementation.
While copying and cloning are great for providing ownership to multiple scopes, they are required when working with immutable storage.