2017-06-16 3 views
1

Ich versuche, einen Prozedurmakro zu schreiben, der eine #[derive()] Eigenschaft für eine Struktur implementiert. Im generierten Implementierungscode muss ich AnyMap verwenden.Eine Kiste in einen Const-Block importieren

Um Multi-Kiste-Importe zu vermeiden, und basierend auf dem, was ich im Code einiger anderer Kisten (nämlich Serde) gelesen habe, habe ich meinen generierten Code in einen const _IMPL_xxx_FOR_xxx :() = { /* generated code */ }; Block geschrieben, aber es kompiliert nicht.

konnte ich mein Problem mit dem folgenden Code

const BLOCK_1:() = { 
    extern crate anymap; 
    use anymap::AnyMap; 
}; 

const BLOCK_2:() = { 
    extern crate anymap; 
    use anymap::AnyMap; 
}; 

fn main() { 
    println!("foo"); 
} 

Der Compiler-Fehler replizieren ich bin immer ist die folgende:

error[E0432]: unresolved import `anymap::AnyMap` 
--> src/main.rs:3:9 
    | 
3 |  use anymap::AnyMap; 
    |   ^^^^^^^^^^^^^^ Maybe a missing `extern crate anymap;`? 

error[E0432]: unresolved import `anymap::AnyMap` 
--> src/main.rs:9:9 
    | 
9 |  use anymap::AnyMap; 
    |   ^^^^^^^^^^^^^^ Maybe a missing `extern crate anymap;`? 

Ist es ein Problem, die spezifisch für AnyMap? Würden Sie von irgendeiner Weise wissen, dass dies (einschließlich vielleicht einen anderen Ansatz zu beheben, um prozedurale Makrocode zu erzeugen, wenn das Muster Ich verwende nicht empfohlen?

Antwort

2

ich dies auf dem Spielplatz replizieren kann einfach mit

const A:() = { 
    extern crate core; 
    use core::option::Option; 
}; 

fn main() {} 

es scheint jedoch, nur die use Aussage gebrochen ist, und ich kann immer noch Elemente aus Kern verwenden, aber ich habe sie jedes Mal explizit zu nennen:

const A:() = { 
    extern crate core; 
    do_stuff!(core::option::Option) 
}; 

der Grund dafür ist, dass use Aussagen sind typischerweise einen Pfad relativ übernehmen an die Wurzel, und es gibt keine Möglichkeit, den Block, in dem Sie sich befinden, explizit zu benennen (self bezieht sich leider auf das aktuelle Modul).

Hier ist eine bessere Problemumgehung - wie bereits erwähnt, verwendet Rust self, um auf das aktuelle Modul verweisen, so können Sie einfach ein Modul in Ihrem Codeblock setzen und dann die use Anweisungen Referenz self.

In Ihrem Fall wäre es:

const BLOCK_1:() = { 
    mod inner { 
     extern crate anymap; 
     use self::anymap::AnyMap; 
    } 
}; 
+0

Danke für diese Elemente @Djzin. Wenn also die Verwendung tatsächlich unterbrochen wird, was ist dann der beste Weg, um Importe zu verwalten, wenn Sie prozedurale Makros verwenden? – Boris

+0

Eine Sache, die Sie tun können, ist, Ihren Code in ein Modul zu setzen, und dann können Sie mit 'use self :: anymap :: Anymap" importieren. Sie können das Modul immer noch in die Constélaration setzen – Djzin

+0

Danke. Ich werde es versuchen – Boris

0

Auf dem spezifischen Thema machen diese Arbeit für verfahrens Makro, eine vorgeschlagene Lösung die benötigte Kiste als Teil der Kiste reexport war die derive Makro enthält (oder der eine, der die Klasse enthält, die ich zu exportieren versuche) mit etwas wie und dann use <my_crate>::anymap::AnyMap;

Verwandte Themen