Ist es in Rost möglich, ein Makro zu schreiben, das andere Makros erzeugt? Angenommen, ich definiere die folgenden zwei Makros:
%Vor%Da die beiden Makros viel Code wiederholen, möchte ich vielleicht ein Makro schreiben, um die Makros zu erzeugen.
Ich habe versucht, ein solches Meta-Makro zu erstellen.
%Vor%, aber die folgenden Fehler erhalten:
%Vor%Bearbeiten: Nachdem ich mit den Makros herumgespielt habe, entdeckte ich, dass ein Makro höherer Ordnung wie erwartet funktioniert, wenn das zurückgegebene Makro keine Argumente erhält. Zum Beispiel der folgende Code
%Vor% druckt hello
Dies wurde kürzlich in # 34925 ermöglicht. Die Antwort unten bezieht sich auf ältere Versionen von Rust.
Dies ist # 6795 und # 6994 und ist momentan nicht direkt möglich. Z.B. Das erste, was man ausprobieren möchte, ist
%Vor%Aber das scheitert mit
%Vor% (Gespeichert # 15640 über den Caret, der auf den (
statt auf den $e
zeigt .)
Der Grund dafür ist, dass die Makroerweiterung "dumm" ist: Sie interpretiert und ersetzt naiv alle Token, sogar innerhalb verschachtelter Makroaufrufe (und macro_rules!
ist ein Makroaufruf). Daher kann es nicht sagen, dass die $e
im Inneren macro_rules!
eigentlich als $e
übrig bleiben sollen: es versucht nur, sie zu ersetzen, wenn define
erweitert wird.
Die zweite Sache, die man versuchen könnte, ist, zusätzliche Argumente an define
zu übergeben, um sie in der Interior-Definition zu platzieren, so dass $e
nicht direkt im verschachtelten Aufruf erscheint:
Das heißt, ich habe $interior: tt
hinzugefügt, um die Erfassung von $e
zu ermöglichen. tt
steht für einen Tokenbaum, bei dem es sich um ein nicht begrenzendes Rohtoken (z. B. $
oder some_ident
) oder eine Folge von Token, die von übereinstimmenden Begrenzern umgeben sind (z. B. (foo + bar fn "baz")
), handelt. Leider scheint es, als wäre die Erweiterung eifrig genug, um auch die Erweiterung $e
zu erweitern:
Es funktioniert gut, wenn der verschachtelte Makro selbst kein Argument hat, weil es keine verschachtelten $...
non-terminals gibt und daher die Erweiterungsphase das oben beschriebene Definitionsproblem nicht erreicht.
Zu guter Letzt können Sie eine Art Code-Sharing erhalten, da Sie Makroaufrufe nach Namen erweitern können:
%Vor% welches 12
ausgibt.
Hier ist ein Beispiel, das funktioniert, vielleicht ein Ausgangspunkt für Sie:
%Vor%Tags und Links rust