gpt4 book ai didi

宏与接受表达式的函数

转载 作者:行者123 更新时间:2023-12-02 06:43:05 25 4
gpt4 key购买 nike

当我尝试以下代码片段时,我发现变量 i 未找到。这是为什么?

function evalMyExpr(expr,n)
for i in 1:n
eval(expr)
end
end

expr1 = Meta.parse("println(\"hello\")")
expr2 = Meta.parse("println(string(i))")

evalMyExpr(expr1,2) # ok
evalMyExpr(expr2,2) # UndefVarError: i not defined

请注意,如果我将其转换为宏,它就会起作用:

macro evalMyExprMacro(expr,n)
quote
for i in 1:$n
$expr
end
end
end

@evalMyExprMacro println(string(i)) 2 # ok

更一般地说,接受表达式作为参数的函数和宏之间有什么区别?

最佳答案

传递给函数的表达式只是在运行时处理的普通值。代码在传递 expr2 时失败的原因是 eval 在全局范围内计算表达式(一般不建议在以下情况下使用 eval功能)。因此,由于在您的情况下变量 i 可能未在全局范围内定义,因此您会收到错误。请参阅在全局范围内定义 i 时的示例:

julia> i = 1000
1000

julia> function evalMyExpr(expr,n)
for i in 1:n
eval(expr)
end
end
evalMyExpr (generic function with 1 method)

julia> expr2 = Meta.parse("println(string(i))")
:(println(string(i)))

julia>

julia> evalMyExpr(expr2,2)
1000
1000

现在 - 在 marcos 中,表达式是在编译时(在代码运行之前)处理的,因此您使用的表达式将被注入(inject)到随后执行的宏生成的代码中。您可以使用@macroexpand查看效果:

julia> macro evalMyExprMacro(expr,n)
quote
for i in 1:$n
$expr
end
end
end
@evalMyExprMacro (macro with 1 method)

julia> @macroexpand @evalMyExprMacro println(string(i)) 2
quote
#= REPL[23]:3 =#
for #6#i = 1:2
#= REPL[23]:4 =#
(Main.println)((Main.string)(#6#i))
end
end

观察宏处理机制将变量名称更改为#6#i,并且它与for 循环中使用的变量名称相匹配。

关于宏与接受表达式的函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56422993/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com