#drop #unsafe #wrapper #into-inner

no-std into_inner_drop

实现 drop 类型 into_inner 方法的辅助库

1 个不稳定版本

0.1.0 2020年1月13日

#2558 in Rust 模式

MITNFA 许可证

11KB
73

Into inner drop

为应同时实现 Dropinto_inner() 方法的类型提供安全的辅助。

关于

存在一种常见的模式,即人们希望有一个在销毁时执行某些操作的类型,但同时也想能够通过某种接受 self 的方法来避免销毁并解构该类型。

此外,有时人们希望在 drop 实现中解构该类型,但由于它是通过可变引用传递的,这并不安全。

在存在这个 crate 之前,需要手动编写 unsafe 代码。这个 crate 负责确保 drop 实现是可靠的。人多力量大,错误更少。

这个 crate 是 no_std

示例

假设你想要一个特殊的类型,它在销毁时打印一个字符串,但又有能力在不打印的情况下取出字符串。这就是你如何使用这个 crate 来实现它

// Not strictly neccessary, but helps encapsulate the inner representation.
mod inner {
    // In fact, you could even avoid this newtype!
    // But in case you have something more complicated, you might need a newtype.
    pub(super) struct PrintOnDrop(pub(super) String);

    // You need this helper type to implement Drop.
    pub(super) enum PrintOnDropImpl {}

    // Drop is implemented a bit differently
    impl into_inner_drop::DetachedDrop for PrintOnDropImpl {
        // This type will be passed to your drop function by value (move).
        type Implementor = PrintOnDrop;

        // The drop implementation. The main difference is passing inner representation by-value.
        fn drop(value: Self::Implementor) {
            // You can destructucutre your type here if you want!
            // E.g. let string = value.0;
            println!("Dropping: {}", value.0);
        }
    }
}

use into_inner_drop::IntoInnerHelper;

// Public representation

/// A String that is printed when dropped.
pub struct PrintOnDrop(IntoInnerHelper<inner::PrintOnDrop, inner::PrintOnDropImpl>);

impl PrintOnDrop {
    /// Crates a string that is printed on drop.
    fn new(string: String) -> Self {
        PrintOnDrop(IntoInnerHelper::new(inner::PrintOnDrop(string)))
    }

    /// Takes out the string, preventing printing on drop.
    fn into_string(self) -> String {
        self.0.into_inner().0
    }
}

fn main() {
    let print_on_drop = PrintOnDrop::new("Hello world!".to_owned());
    let dont_print_on_drop = PrintOnDrop::new("Hello Rustceans!".to_owned());

    let string = dont_print_on_drop.into_string();
    println!("NOT on drop: {}", string);
}

如你所见,代码有一些样板,但没有 unsafe。我正在尝试编写一个宏来使其更容易。请参见 GitHub 上的相关问题以参与其中。

许可证

MITNFA

无运行时依赖