I was thinking of the following code, where I believe the assignment to y is actually free. Though apparently this isn't called a "move".
let x = <<large owned type like [char; 1000]>>;
let y = x;
More info: https://doc.rust-lang.org/rust-by-example/scope/move.htmlIn the example from the article it is probably actually a copy because the value was originally on the parent thread's stack, which will be reused after the function returns, so the value will need to be copied to the new thread's stack.
However it is important to not that it isn't a deep/recursive bitwise copy. It just needs to copy the HashMap itself (which is probably a handful of words).
So yes, it is doing a bitwise copy, but this is also very cheap. It will be much, much cheaper than spawning the thread.
std::map<...> foo;
someFunction(std::move(foo));
And not moving a pointer like: std::unique_ptr<std::map<...>> foo = ...;
someFunction(std::move(foo));
So it copies sizeof(std::map<...>), not a pointer.I.e. a `HashMap` struct, or `Vec` struct don't directly contain the data.
For example the `Vec` is defined internally as something similar to:
`struct Vec<T> { data: *mut [T], capacity: usize, len: usize, marker: PhantomData<T> }`
(Slightly simplified, not actual Vec type).
So a move of a Vec copies at most 3 usize (24 bytes on 64bit systems), similar thinks apply for a HashMap.
Additionally the copy can often be elided through compiler optimizations.
As a interesting side note a new empty Vec/HashMap will not actually allocate any memory, only once elements get added it will start doing so. This is why it crates vec's of vecs of length 1. Or else it wouldn't need to do "number of element" free calls.
However, these copies can often be elided by optimizations.