3
我发现一个unless
宏的例子在写朱莉娅here如下:这个Julia宏为什么不需要`esc`?
macro unless(test, branch)
quote
if !$test
$branch
end
end
end
然而,当我尝试使用它,它失败(显然存在卫生问题,但我想不出它完全)。下面是我使用的测试:
x, y = 0, 1
@unless (x == 5) begin # should execute
y = 3
end
@unless (x == 0) begin # should not execute
y = 5
end
@assert y == 3 # FAILS! SAYS y is 0
现在,我可以逃避仅分支,使这项工作,而不是测试:
macro unless(test, branch)
quote
if !$test
$(esc(branch))
end
end
end
我的问题是:为什么它足以只逃避分支但不是测试?现在我尝试了宏观展开。在第一种情况下,如果没有esc
,我得到这个:
julia> macroexpand(:(@unless (x == 5) begin y = 3 end))
quote # none, line 3:
if !(x == 5) # none, line 4:
begin # none, line 1:
#2#y = 3
end
end
end
现在虽然既不宏参数被逃脱,只有y
被gensymed!任何人都可以解释为什么这是事实吗? (我知道第二个版本的工作原理是因为当我逃离分支时,y并没有得到gensymed,并且宏如预期的那样扩展到y = 3
。但是我完全不知道为什么x
没有被gensymed即使有是没有用的esc
)
好的,我明白了,所以'x'被分类为全局和'y'作为本地。全局通过而不会被gensymed。当地人得到gensymed。转义可以防止gensymming,但对全局变量不是必需的。有道理,但不是很明显。 :) –