2016-10-02 4 views
4

Ich verwende eine Bibliothek für String-Interning (string-cache), die Makros zum effizienten Erstellen von Elementen verwendet (atom!). Jedoch zur Vereinfachung hier ist ein ähnliches Makro, das das ProblemBestellung Makroargumentausführung

macro_rules! string_intern { 
    ("d") => ("Found D"); 
} 

sagen muss ich nennen das Makro von einem anderen Makro und geben ihm eine String-Version einer Kennung demonstriert.

macro_rules! print_ident { 
    ($id:ident) => (
     string_intern!(stringify!($id)); 
    ); 
} 

jedoch Aufruf dieses Makro

fn main() { 
    print_ident!(d); 
} 

schlägt mit Fehler:

error: no rules expected the token `stringify` 
--> <anon>:7:24 
    | 
7 |   string_intern!(stringify!($id)); 
    |      ^^^^^^^^^ 

Playground link

Ich weiß stringify! richtig d bespannen "d", Identifier konvertiert, weil gi ving es zu println! funktioniert wie erwartet. Gibt es eine Möglichkeit, die Kennung, die ich in String umgewandelt werden soll, an string_intern zu übergeben?

Antwort

9

println! können Sie dies tun, weil es format_args! unter der Decke verwendet, die ein Compiler bereitgestellte „intrinsische“ ist, die gewaltsam ihr erstes Argument vor mit wertet. Sie können dies nicht von einem benutzerdefinierten Makro aus tun; Sie müssten ein Compiler-Plugin schreiben (was einen nächtlichen Compiler und keine Garantie für Stabilität erfordert).

Also ja; du kannst nicht. Es tut uns leid. Das einzige, was Sie tun können, ist, das Makro so zu definieren, dass Sie kein tatsächliches Zeichenfolgenliteral benötigen, oder ändern Sie, wie Sie es aufrufen.

0

Deine Definition von string_intern! ist ein wörtlich "d" und nichts anderes erwartet, aber Sie in diesen Token vorbei: stringify, !, ... die, warum es nicht. Die Definition von string_intern!, die Sie wollen, ist wahrscheinlich:

macro_rules! string_intern { 
    ($e:expr) => { 
     match $e { 
      "d" => "Found D", 
      _ => "Not found", 
     } 
    } 
} 

, die jeden Ausdruck annehmen kann, die zu einem String-Typ auswertet.

+1

Es ist nur eine Kurzschrift. Im Grunde kann ich Sie nicht bitten, 'string-cache' herunterzuladen, um dieses Beispiel zu lösen, also ist dies MVP für dieses Problem. –

+0

@DanielFath Ah! Ich denke, ich habe deine Absicht nicht richtig verstanden ... Du wolltest unbedingt Kompilierzeit-Abgleich ... – John