Ich möchte ein Makro erstellen, um einen langen Ausdruck zu ersetzen, der in mehreren Funktionen verwendet wird, um die Lesbarkeit von Code zu verbessern. Jede Funktion hat den gleichen Namen für ein bestimmtes Argument, das im Makro verwendet wird, aber beim Kompilieren der Funktion sagt Julia, dass die im Makro verwendete Variable nicht definiert ist, selbst wenn es maskiert ist. Minimal Beispiel:Julia - UndefVarError in Makro, wenn in Funktion verwendet, aber nicht in REPL
julia> macro mtest()
esc(x)
end
@mtest (macro with 1 method)
julia> ftest(x) = @mtest
ERROR: UnderVarError: x not defined
Jetzt wird es seltsam:
julia> x = 1
1
julia> @mtest
1
julia> ftest(x) = @mtest
ftest (generic function with 1 method)
julia> ftest(2)
1
Warum nicht einfach diese Funktionsdefinition ftest(x) = x
bewerten? Wie kann ich dem Makro mitteilen, das x
aus dem Bereich der aufrufenden Funktion statt von der REPL zu verwenden? Ich mag ein Makro verwenden, um einfach einen wörtlichen Textblock zu ersetzen, wie in der C-Bibliothek Ich verwende:
#define CHECK_STUFF \
big \
complicated \
expression \
involving x;
void func(x, y, z) {
//stuff
CHECK_STUFF
//more stuff
}
In diesem Fall CHECK_STUFF
muss Makro sein, nicht eine Funktion, denn sie enthält a goto
zu einem Etikett in func
. Meine Aufgabe ist es, dies zu Julia zu übersetzen.
Im Makro muss 'x' das Symbol': x' sein. Ihr Makro bezieht sich auf die globale Variable 'x', die nur existiert, nachdem Sie sie in der REPL definiert haben. Siehe auch http://stackoverflow.com/q/37358528/6172490. – tim
Um genauer zu sein, beziehen sich Variablen, die in einem Makro verwendet werden, auf die globalen Variablen in dem Modul, in dem das Makro definiert ist. In Ihrem Fall ist es im Hauptmodul definiert und bezieht sich somit auf dort definiertes "x". Ihr Makro gibt dann den Ausdruck zurück, der nur aus dem Literalwert von "x" besteht. Das Escapen ändert in diesem Fall nichts. Siehe die Ausgabe von 'macroexpand', was sehr hilfreich beim Schreiben von Makros ist. – tim