Can please anyone explain Pin & Unpin?
I understand perfectly fine why it is needed: If there is a struct that has a
and there is a pointer b
in the struct that points to a
, we cannot "just" move the struct. Because b
's value is not going to be updated, which results in dangling reference.
So far so good and simple. In C++ we would say something like this to prevent this:
// Forbid copy:
T(const T &) = delete;
T &operator=(const T &) = delete;
// Forbid move:
T(T &&) = delete;
T &operator=(T &&) = delete;
But in Rust, there are 4 options:
- Pin<> + Unpin
- Pin<> + !Unpin
- Unpin
- !Unpin
Rust async book says this:
The
Pin
type wraps pointer types, guaranteeing that the values behind the pointer won't be moved if it is not implementingUnpin
But why do we then need Pin? It is like saying:
- If you go to supermarket (== wrap T in Pin<>) and it is night (T is Unpin), then there is moon
- If you go to supermarket (== wrap T in Pin<>) and it is day (T is !Unpin), then there is no moon.
What is the point to say "If you go to supermarket" if it has no effect? Based on that excerpt from the book, Pin
along does not guarantee anything. Ultimately, !Unpin
and Unpin
is what is important.
And overall, what is the purpose to create a mechanism (Pin) effect of which can be overridden in another place (marker Unpin)? I either want to forbid move or not. Why I need to think about if that type has Unpin marker or not?
From rust async book:
Pointers to
Unpin
types can be freely placed into or taken out ofPin
. For example,u8
isUnpin
, soPin<&mut u8>
behaves just like a normal&mut u8
.
What is meant by "placed into or taken out of Pin
"? In computers, we have memory and addresses (which are ultimately just numbers). A Pin<>
field is likely just a number (an address in memory). How can anyone place pointer in number? Did they mean "change the value of Pin field"? Change pointer? I can change pointer, making it point to another object, but I am not sure what "pointer to an object ca be placed into number".