#智能指针 #对象 #手动 #释放 #销毁 #self #关闭

关闭

特质 + 智能指针,用于手动对象销毁

4 个版本

0.2.0 2022 年 4 月 20 日
0.1.2 2022 年 4 月 14 日
0.1.1 2022 年 4 月 14 日
0.1.0 2022 年 4 月 14 日

2475Rust 模式

MIT 许可证

13KB
108

Documentation Crates.io License: MIT

Rust 特质 + 智能指针,用于手动对象销毁

此软件包引入了用于手动对象销毁的 Close 特质。虽然与 Drop 的目的相似,但主要区别在于 close 方法会获取 self 的所有权,并允许错误传播。为了与 Drop 一起使用,此软件包还引入了 Closing<T: Close> 智能指针,这是一个零成本抽象,如果对象未被手动关闭,则在其释放时关闭包含的对象。

动机

在需要销毁序列执行释放或移动成员的情况下,拥有 self 的所有权很有用。使用 drop,这需要像以下示例中那样将成员放在一个 Option 中,在该示例中,在继续拆解过程之前连接一个线程(移动其句柄)。这种结构的缺点是增加了运行时成本,并降低了通过选项访问数据后的可用性。

struct DeepThought(Option<std::thread::JoinHandle<u32>>);

impl DeepThought {
    fn new() -> Self {
        Self(Some(std::thread::spawn(|| 42)))
    }
    fn thread(&self) -> &std::thread::Thread {
        self.0.as_ref().unwrap().thread() // <-- not great
    }
}

impl Drop for DeepThought {
    fn drop(&mut self) {
        match self.0.take().unwrap().join() {
            Err(e) => std::panic::resume_unwind(e),
            Ok(_answer) => /*... teardown ...*/ ()
        }
    }
}

使用 close 而不是 drop,我们可以避免选项舞蹈,并像自然那样编写东西

use close::{Close, Closing};

struct DeepThought(std::thread::JoinHandle<u32>);

impl DeepThought {
    fn new() -> Closing<Self> {
        Self(std::thread::spawn(|| 42)).into()
    }
    fn thread(&self) -> &std::thread::Thread {
        self.0.thread() // <-- better!
    }
}

impl Close for DeepThought {
    type Error = String;
    fn close(self) -> Result<(), Self::Error> {
        match self.0.join() {
            Err(e) => Err(format!("thread panicked: {:?}", e)),
            Ok(_answer) => /*... teardown ...*/ Ok(()),
        }
    }
}

请注意,除了避免 Option 之外,构造函数现在返回 Closing 智能指针。因此,第二个实现可以像前者一样精确地使用,使用自动解引用来访问成员和方法,并在对象超出作用域时连接线程。区别在于后者允许更易于使用的实现,不产生任何运行时成本,并在需要错误处理的情况下允许手动关闭。

没有运行时依赖