コードの可読性を向上させるために、いくつかの関数で使用されている長い式をマクロに置き換えたい。各関数はマクロで使用されている特定の引数と同じ名前ですが、関数をコンパイルするとき、マクロで使用される変数はエスケープされても定義されていません。最小限の例:Julia - UndefVarError関数で使用されていて、REPLで使用されていない
julia> macro mtest()
esc(x)
end
@mtest (macro with 1 method)
julia> ftest(x) = @mtest
ERROR: UnderVarError: x not defined
今では奇妙な取得します。
julia> x = 1
1
julia> @mtest
1
julia> ftest(x) = @mtest
ftest (generic function with 1 method)
julia> ftest(2)
1
なぜ、この関数の定義は、単にftest(x) = x
に評価されませんか? x
をREPLからではなく呼び出し関数のスコープから使用するようにマクロに指示するにはどうすればよいですか?それが含まれているため、
#define CHECK_STUFF \
big \
complicated \
expression \
involving x;
void func(x, y, z) {
//stuff
CHECK_STUFF
//more stuff
}
この場合CHECK_STUFF
はマクロでなければならないない機能を:私は単に私が使用していますCライブラリのように、テキストのリテラルブロックを置換するマクロを使用しますgoto
のラベルをfunc
に貼り付けます。私の仕事はこれをジュリアに翻訳することです。
マクロでは、 'x'はシンボル':x'である必要があります。あなたのマクロは、グローバル変数 'x'を参照します。これはREPLで定義した後にのみ存在します。 http://stackoverflow.com/q/37358528/6172490も参照してください。 – tim
より具体的には、マクロで使用される変数は、マクロが定義されているモジュール内のグローバル変数を参照します。あなたの場合、それはメインモジュールで定義されており、したがってそこに定義されている 'x'を指します。あなたのマクロは 'x'のリテラル値だけからなる式を返します。エスケープしてもその場合は何も変わりません。 'macroexpand'の出力を見てください。これは、マクロを書くときに非常に役に立ちます。 – tim