Globals of type Option<…> in Rust

2019-03-01 18:13发布

I can not get the following piece of code to work:

extern crate gtk

use gtk::prelude::*
use gtk::Window;
use gtk::WindowType;
// ...

static mut appWindow: Option<Window> = None;

fn main() {
    // ...
    appWindow = Some(Window::new(WindowType::Toplevel))
    // ...
}

The compiler produces the error:

error: mutable statics are not allowed to have destructors [E0397]
static mut appWindow: Option<Window> = None;

Surrounding everything with unsafe { ... } doesn't help.

标签: rust global
1条回答
我命由我不由天
2楼-- · 2019-03-01 18:44

Here's code that reproduces the same error that you've shown:

struct Foo;

impl Drop for Foo {
    fn drop(&mut self) {}
}

static mut f: Foo = Foo;

fn main() {}

Produces the errors:

error: mutable statics are not allowed to have destructors [E0397]
static mut f: Foo = Foo;
                    ^~~

error: statics are not allowed to have destructors [E0493]
static mut f: Foo = Foo;
                    ^~~

As the message says, Rust disallows having any kind of static item with destructors. A proposed change to the language discusses the origin of this:

This was historically motivated by the question of when to run the destructor:

  • There where worries about supporting life before/after main() for, eg, static variables due to them having historically caused trouble in, eg, C++ code bases.
  • Leaking the destructor was also for the most time not known to be a feasible option due to leaking possibly being bad.

RFC 1440 has been accepted to allow these types. As of Rust 1.9, there is an unstable feature that allows them: #![feature(drop_types_in_const)].

As the RFC says:

Destructors do not run on static items (by design), so this can lead to unexpected behavior when a type's destructor has effects outside the program (e.g. a RAII temporary folder handle, which deletes the folder on drop). However, this can already happen using the lazy_static crate.

Which leads to an alternate solution before the feature is stabilized: you can create a non-mutable static variable with lazy_static, which can then be wrapped in a thread-safe mutability wrapper. The type may contain a destructor:

How do I create a global, mutable singleton?

查看更多
登录 后发表回答