There are some similar questions, but the answers require the field to implement Default
or some way to initialize another value with the type of the field.
We have a Node
which has a value
of type T
:
struct Node<T> {
value: T,
next: Option<Box<T>>
}
It has a method which moves value
from a Node
:
impl<T> Node<T> {
fn value(self) -> T {
self.value
}
}
The code above compiles. But if we implement Drop
for Node
:
impl<T> Drop for Node<T> {
fn drop(&mut self) {}
}
Then we will get a compile error:
error[E0509]: cannot move out of type `Node<T>`, which implements the `Drop` trait
| self.value
| ^^^^^^^^^^
| |
| cannot move out of here
| move occurs because `self.value` has type `T`, which does not implement the `Copy` trait
I guess it doesn't compile because if we implement a custom Drop
, we need to make sure not to drop value
field if the drop happens at the end of value
method's block. However, we cannot check that; and even if we could, the compiler cannot statically check that we do it.
One way to workaround this is to store value
field as Option<T>
. But suppose that we don't want to use Option
for some reasons (the overhead, etc),
What else can we do to have both a custom Drop
and a value
method that moves value
field?
I guess we have to use some unsafe
approach and that's fine.