表达式 eval 中未定义 Julia 局部变量
Julia local variable not defined in expression eval
给定以下函数,
function floop(exp)
a = 5
b = 10
ex = Expr(:call, :+, 1, exp);
return eval(ex);
end
如果我那么运行
floop(Symbol("b"))
我收到一条错误消息,指出 b
未定义。为什么这不起作用?我怎样才能使这项工作?
让 Julia 变得快速的关键因素之一是 eval 始终在全局范围内运行。这意味着它永远不能引用局部变量。
您可以执行类似以下宏的操作,在扩展时选择一个值,具体取决于静态已知 Symbol
:
julia> macro floop(selector::QuoteNode)
choices = Dict(:a => 5, :b => 10)
ex = :(1 + $(choices[selector.value]))
return ex
end
@floop (macro with 1 method)
julia> @macroexpand @floop(:a)
:(1 + 5)
julia> @macroexpand @floop(:b)
:(1 + 10)
julia> @floop(:c)
ERROR: LoadError: KeyError: key :c not found
Stacktrace:
[1] getindex(::Dict{Symbol,Int64}, ::Symbol) at ./dict.jl:477
[2] @floop(::LineNumberNode, ::Module, ::QuoteNode) at ./REPL[27]:3
in expression starting at REPL[33]:1
julia> s = :a; @floop(s)
ERROR: LoadError: MethodError: no method matching @floop(::LineNumberNode, ::Module, ::Symbol)
Closest candidates are:
@floop(::LineNumberNode, ::Module, ::QuoteNode) at REPL[1]:2
in expression starting at REPL[2]:1
如何实际存储实际值取决于您。 const
全局字典是一个选项,或者只是一个简单的 if
链。
(在QuoteNode
中其实可以有除Symbol
之外的其他东西,但是很难将它们拼接到宏调用中,它们也只会引发一个KeyError
,所以我没有包括任何额外的处理。)
给定以下函数,
function floop(exp)
a = 5
b = 10
ex = Expr(:call, :+, 1, exp);
return eval(ex);
end
如果我那么运行
floop(Symbol("b"))
我收到一条错误消息,指出 b
未定义。为什么这不起作用?我怎样才能使这项工作?
让 Julia 变得快速的关键因素之一是 eval 始终在全局范围内运行。这意味着它永远不能引用局部变量。
您可以执行类似以下宏的操作,在扩展时选择一个值,具体取决于静态已知 Symbol
:
julia> macro floop(selector::QuoteNode)
choices = Dict(:a => 5, :b => 10)
ex = :(1 + $(choices[selector.value]))
return ex
end
@floop (macro with 1 method)
julia> @macroexpand @floop(:a)
:(1 + 5)
julia> @macroexpand @floop(:b)
:(1 + 10)
julia> @floop(:c)
ERROR: LoadError: KeyError: key :c not found
Stacktrace:
[1] getindex(::Dict{Symbol,Int64}, ::Symbol) at ./dict.jl:477
[2] @floop(::LineNumberNode, ::Module, ::QuoteNode) at ./REPL[27]:3
in expression starting at REPL[33]:1
julia> s = :a; @floop(s)
ERROR: LoadError: MethodError: no method matching @floop(::LineNumberNode, ::Module, ::Symbol)
Closest candidates are:
@floop(::LineNumberNode, ::Module, ::QuoteNode) at REPL[1]:2
in expression starting at REPL[2]:1
如何实际存储实际值取决于您。 const
全局字典是一个选项,或者只是一个简单的 if
链。
(在QuoteNode
中其实可以有除Symbol
之外的其他东西,但是很难将它们拼接到宏调用中,它们也只会引发一个KeyError
,所以我没有包括任何额外的处理。)