繁体   English   中英

如何在 Rust 库中运行清理代码?

[英]How can I run clean-up code in a Rust library?

我正在制作一个跨平台的终端库。 因为我的库更改了终端的状态,所以我需要在进程结束时恢复对终端所做的所有更改。 我现在正在实现这个功能,并在思考如何最终恢复到原始终端状态。

我认为在程序启动时初始化了一个静态变量,当程序结束时,这个静态变量将被销毁。 由于我的静态变量是一个实现了Drop特性的结构,它会在程序结束时被删除,但事实并非如此,因为字符串“drop called”永远不会被打印:

static mut SOME_STATIC_VARIABLE: SomeStruct = SomeStruct { some_value: None };

struct SomeStruct {
    pub some_value: Option<i32>,
}

impl Drop for SomeStruct {
    fn drop(&mut self) {
        println!("drop called");
    }
}

为什么程序结束时不调用drop() 我的想法是错误的,我应该以另一种方式这样做吗?

在库中强制执行初始化和清理代码的一种方法是引入一个只能用公共new()函数构造的Context类型,并实现Drop trait。 库中每个需要初始化的函数都可以接受一个Context作为参数,因此用户需要在调用这些函数之前创建一个。 任何清理代码都可以包含在Context::drop()

pub struct Context {
    // private field to enforce use of Context::new()
    some_value: Option<i32>,
}

impl Context {
    pub fn new() -> Context {
        // Add initialization code here.
        Context { some_value: Some(42) }
    }
}

impl Drop for Context {
    fn drop(&mut self) {
        // Add cleanup code here
        println!("Context dropped");
    }
}

// The type system will statically enforce that the initialization
// code in Context::new() is called before this function, and the
// cleanup code in drop() when the context goes out of scope.
pub fn some_function(_ctx: &Context, some_arg: i32) {
    println!("some_function called with argument {}", some_arg);
}

Rust 的原则之一是在 main 之前没有生命,这意味着main 之后没有生命

在 main 之前或之后正确排序构造函数和析构函数存在相当大的挑战。 在 C++ 中,这种情况被称为静态初始化顺序失败,虽然有解决方法,但它的挂件(静态破坏顺序失败)没有。

在 Rust 中, 'static生命周期'static加剧了挑战:在'static中运行析构函数可能会导致观察到部分被破坏的其他静态。 这是不安全的。

为了允许安全销毁静态,该语言需要引入'static生命周期'static子集来命令'static的构建/销毁,同时让这些生命周期仍然是'static来自main内部'static ......


如何在程序开始/结束时运行代码?

只需在main的开始/结束处运行代码。 请注意,在main开头构建的任何结构都将在其末尾以与构建相反的顺序丢弃。

如果我不是自己写main呢?

问问main ,很好。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM