【问题标题】:How can I run clean-up code in a Rust library?如何在 Rust 库中运行清理代码?
【发布时间】:2018-07-21 18:59:42
【问题描述】:

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

我以为程序启动时会初始化一个静态变量,而当程序结束时,这个静态变量会被销毁。由于我的静态变量是一个实现了 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()?我的想法是不是错了,我应该换一种方式吗?

【问题讨论】:

标签: static rust destroy


【解决方案1】:

Rust 的一个原则是 no life before main,这意味着 main 之后没有生命

在 main 之前或之后正确排序构造函数和析构函数存在相当大的挑战。在 C++ 中,这种情况被称为static initialization order fiasco,虽然有解决办法,但它的挂件(静态销毁命令惨败)却没有。

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

为了允许安全地销毁静态变量,该语言需要引入 'static 生命周期的子集,以便对静态变量的构造/销毁进行排序,同时让这些生命周期仍然是 'static 从内部 main...


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

只需在main 的开头/结尾运行代码。请注意,在main 开头构建的任何结构都将以相反的构建顺序在其末尾被删除。

如果我不是自己写main

main的作者,很好。

【讨论】:

  • 感谢您的信息,有道理。由于我正在编写一个库,因此可能会要求用户从我的库中执行某些功能。我得考虑一下。
【解决方案2】:

在库中强制执行初始化和清理代码的一种方法是引入只能使用公共 new() 函数构造的 Context 类型,并实现 Drop 特征。库中需要初始化的每个函数都可以将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);
}

【讨论】:

  • 标记你的答案,因为它是解决问题的一种方式。
猜你喜欢
  • 1970-01-01
  • 2014-11-06
  • 2014-01-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-06-20
  • 2015-03-29
  • 1970-01-01
相关资源
最近更新 更多