摘要:我正在使用资源使用者类型Consumer
和资源类型Resource
.接口的相关部分如下:
impl Consumer {
pub fn consume(&self, r: Resource);
}
API是这样的,所以没有其他安全的方式让Consumer
人消费资源.Resource
不是Copy
.
我想创建一个具有以下接口的类型WithConsumer<‘a>
:
impl<‘a> WithConsumer<‘a> {
pub fn new(r: Resource, c: &’a Consumer) -> Self;
pub fn into_inner(self) -> Resource;
}
impl<‘a> AsRef<‘a, Resouce> for WithConsumer<‘a>;
impl<‘a> AsMut<‘a, Resource> for WithConsumer<‘a>;
impl<‘a> Drop for WithConsumer<‘a>;
其中,代码std::men::drop(WithConsumer::new(resource, consumer))
应等于consumer.consume(resource)
,并且所有其他实现细节都应具有其明显的属性.
显然,这不能在安全Rust 中做到.以下是一个不安全的实现(明显省略了几个位):
use std::mem::ManuallyDrop;
pub struct WithConsumer<‘a> {
r: ManuallyDrop<Resource>,
c: &’a Consumer,
}
impl WithConsumer<‘a> {
pub fn into_inner(mut self) -> Resource {
unsafe {
let answer = ManuallyDrop::take(&mut self.r);
std::mem::forget(self);
answer
}
}
}
impl<‘a> Drop for WithConsumer<‘a> {
fn drop(&mut self) {
unsafe { self.c.consume(ManuallyDrop::take(&mut self.r))
}
}
}
这是一个安全的抽象概念吗?在crates.io上,标准库或任何好的 crate 中有没有已经做过这样的事情的部分?这似乎是一个足够明显的问题,它应该有一个众所周知的、已经写好的解决方案.