为什么我在 Julia 宏中得到一个 UndefVarError
Why do I get an UndefVarError in Julia macro
我正在学习 Julia,特别是我正在尝试掌握宏,所以我发现,除其他外 Some useful macros for Julia - Github,在破译它们的过程中,我在 REPL 中得到了这种行为:
julia> macro once_then(expr::Expr)
@assert expr.head == :while
esc(quote
$(expr.args[2]) # body of loop
$expr # loop
end)
end
@once_then (macro with 1 method)
julia> i = 0
0
julia> @once_then while i < 10
i += 1
end
ERROR: UndefVarError: i not defined
Stacktrace:
[1] macro expansion at ./REPL[34]:2 [inlined]
[2] top-level scope at ./REPL[31]:5
julia> i
1
它显然在循环的第一次迭代中访问了 i
,因为它增加了它,但随后 i
在第一次循环结束之间的某个地方变成了 Undef
ed循环和第二个的开始?
据我所知,esc
之后的括号应该包括循环结束之前的所有内容...
我只是将代码复制粘贴到终端中,我从 Julia language - Until loop 中的 @until
宏中得到了相同的行为,所以我认为问题不会来自代码本身...我遗漏了什么重要的东西吗?
(顺便说一句,我是 运行 1.0.4,所以这不应该是向后兼容性的问题...)
你的宏没问题。问题是所涉及变量的范围。 (有关更多信息,请查看:JuliaLang - Scope of Variables
简而言之,i = 0
中的变量i
是全局作用域,而循环是局部作用域。在 REPL 中,您可以添加关键字 global
让您的代码工作:
julia> @once_then while i < 10
global i += 1
end
另一个选项是在函数中完成所有这些,因此所有变量都具有局部作用域:
function fn()
i = 0
@once_then while i < 10
i += 1
end
return i
end
我正在学习 Julia,特别是我正在尝试掌握宏,所以我发现,除其他外 Some useful macros for Julia - Github,在破译它们的过程中,我在 REPL 中得到了这种行为:
julia> macro once_then(expr::Expr)
@assert expr.head == :while
esc(quote
$(expr.args[2]) # body of loop
$expr # loop
end)
end
@once_then (macro with 1 method)
julia> i = 0
0
julia> @once_then while i < 10
i += 1
end
ERROR: UndefVarError: i not defined
Stacktrace:
[1] macro expansion at ./REPL[34]:2 [inlined]
[2] top-level scope at ./REPL[31]:5
julia> i
1
它显然在循环的第一次迭代中访问了 i
,因为它增加了它,但随后 i
在第一次循环结束之间的某个地方变成了 Undef
ed循环和第二个的开始?
据我所知,esc
之后的括号应该包括循环结束之前的所有内容...
我只是将代码复制粘贴到终端中,我从 Julia language - Until loop 中的 @until
宏中得到了相同的行为,所以我认为问题不会来自代码本身...我遗漏了什么重要的东西吗?
(顺便说一句,我是 运行 1.0.4,所以这不应该是向后兼容性的问题...)
你的宏没问题。问题是所涉及变量的范围。 (有关更多信息,请查看:JuliaLang - Scope of Variables
简而言之,i = 0
中的变量i
是全局作用域,而循环是局部作用域。在 REPL 中,您可以添加关键字 global
让您的代码工作:
julia> @once_then while i < 10
global i += 1
end
另一个选项是在函数中完成所有这些,因此所有变量都具有局部作用域:
function fn()
i = 0
@once_then while i < 10
i += 1
end
return i
end