Выражения, передаваемые в функции, являются просто обычными значениями, которые обрабатываются во время выполнения.Причина сбоя кода при его передаче 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 обрабатываются во время компиляции (до запуска кода), поэтому используемое вами выражение вставляется в сгенерированный кодмакросом, который выполняется впоследствии.Вы можете увидеть эффект, используя @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
петля.