Assume that a struct holds a precious resource. When that struct is being dropped, we’d like to to something more with that precious resource.
Currently, with Drop::drop(&mut self)
the struct needs to wrap the resource into some other container to be able to move it out from within Drop::drop
.
Example:
fn do_something_more_with_precious_resource(resource: PreciousResource) {
}
struct PreciousResource;
struct Guard {
resource: Option<PreciousResource>,
}
impl Guard {
fn normal_and_frequent_access_to_resource(&self) {
// For each access, have to pay runtime cost to check for presence:
self.resource.as_ref().unwrap();
}
}
impl Drop for Guard {
fn drop(&mut self) {
do_something_more_with_precious_resource(self.resource.take().unwrap())
}
}
Wouldn’t it be more ergonomic and efficient to define a DropConsuming
like this:
trait DropConsuming {
fn drop_consuming(self);
}
struct Guard2 {
resource: PreciousResource,
}
impl Guard2 {
fn normal_and_frequent_access_to_resource(&self) {
// Can access the resource without having to unwrap some Option first
&self.resource;
}
}
impl DropConsuming for Guard2 {
fn drop_consuming(self) {
// Can move out of self
do_something_more_with_precious_resource(self.resource)
}
}
What’s the reason behind this quite fundamental choice?