2016-06-08 5 views
1

Ich kann das folgende Stück Code an der Arbeit:Globals vom Typ Option <...> in Rust

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)) 
    // ... 
} 

Der Compiler erzeugt den Fehler:

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

aller Umgebung mit unsafe { ... } nicht hilft .

+2

'Optional' ist kein Typ von der Standardbibliothek zur Verfügung gestellt. Woher kommt das? Wird es von der GTK-Kiste bereitgestellt? Bitte erstellen Sie ein [MCVE], wenn Sie eine Frage zu Stack Overflow stellen. Sie könnten auch interessiert sein an [Wie erstelle ich eine globale, veränderbare Singleton?] (Http://stackoverflow.com/questions/27791532/how-do-i-create-a-global-mutable-singleton). Sie sollten auch beachten, dass der Rust-Stil "snake_case" ist, nicht "camelCase" (sollte "app_window" sein). – Shepmaster

+0

@Shempmaster Es ist von 'std :: option :: Option', soweit es mich betrifft. Aber es scheint, dass ich es aus irgendeinem Grund nicht explizit importieren muss. Und das explizite Importieren ändert nichts. – CodenameLambda

+0

Siehe [diesen Link] (http://rustbyexample.com/std/option.html). Dies ist, wo ich das 'Optional <...>'-Teil von bekommen habe. – CodenameLambda

Antwort

3

Hier Code ist, die denselben Fehler wiedergibt, die Sie gezeigt haben:

struct Foo; 

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

static mut f: Foo = Foo; 

fn main() {} 

die Fehler Erzeugt:

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; 
        ^~~ 

Wie die Meldung sagt, nicht zulässt Rust jede Art von statischen Element mit mit Destruktoren. Eine vorgeschlagene change to the language bespricht der Ursprung dieses:

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 wurde diese Art zu ermöglichen, akzeptiert. Ab Rust 1.9 gibt es eine instabile Funktion, die es ihnen ermöglicht: #![feature(drop_types_in_const)].

Wie die RFC sagt:

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.

die zu einer alternativen Lösung führt, bevor die Funktion stabilisiert: Sie haben eine nicht-veränderbare statische Variable mit lazy_static erstellen können, die dann in einem gewickelt werden können Thread-sicher Wandelbarkeits-Wrapper. Der Typ kann eine destructor enthalten:

How do I create a global, mutable singleton?

+0

Vielen Dank für die Erklärung, es ist eigentlich ziemlich interessant. Aber: Gibt es eine Möglichkeit, 'Optional' oder etwas anderes zu verwenden, um die Möglichkeit zu haben, einen' None'-ähnlichen Wert zu verwenden? Oder muss ich mit einer "struct" umgehen, die das 'Optional' enthält? (Ohne Verwendung instabiler Funktionen) – CodenameLambda

+0

@CodingLambdas da * noch * ist kein 'optionaler' Typ. Wenn er in eine "Option" gestellt wird, hat "Option" dann einen Destruktor, der möglicherweise aufgerufen werden muss, was im stabilen Rust ab 1.9 nicht erlaubt ist. – Shepmaster

+0

Ok, ich habe eine Struktur erstellt, die das Fenster enthält. Es funktioniert immer noch nicht (gleicher Fehler). Und ich habe 'Drop' nicht implementiert. – CodenameLambda