【发布时间】:2021-01-12 01:37:27
【问题描述】:
我有一个函数,我想在其中使用作为参数传递给函数的内插文字来评估表达式列表,并将结果分配给新数组。以前我可以很简单地做到这一点:
array_of_expr = Any[:(A * 5), :(B * 6 * T)]
arglist = [:A; :B; :T]
test_input = [1e5, 1e1, 100]
@eval begin
function interpolate_all($(arglist...))
result_array = $(Expr(:vcat, array_of_expr...))
end
end
interpolate_all(test_input...)
返回预期结果:
2-element Array{Float64,1}: 500000.0 6000.0
(我知道@eval 的代码似乎不必要地复杂--这是因为在完整版代码中,arglist 的长度约为 500 项。这在完整版中导致了一些编译器错误代码,所以我在这里循环 array_of_expr 的尝试是我测试的一部分,以找出确切的错误,也帮助我更好地理解元编程/变量范围。)
我可以索引array_of_expr 并在此 MWE 中手动评估单个元素:
@eval begin
function interpolate_one($(arglist...))
result_array = similar(array_of_expr)
println("evaluating $(array_of_expr[2])")
result_array = $(array_of_expr[2])
println(result_array)
end
end
interpolate_one(test_input...)
返回:
evaluating B * 6 * T 6000.0
这是预期的行为。但是如果我尝试遍历array_of_expr,我会遇到各种错误。下面忽略迭代器i,只打印符号表达式:
@eval begin
function interpolate_1by1($(arglist...))
result_array = similar(array_of_expr)
# this doesn't work, it just gives the symbolic expression, basically ignoring the $:
for i in range(1, length=length(array_of_expr))
result_array[i] = ($array_of_expr[i])
end
println(result_array)
end
end
interpolate_1by1(test_input...)
下面报告i没有定义,我理解是因为expressions are evaluated in the global scope, not local:
@eval begin
function interpolate_1by1($(arglist...))
result_array = similar(array_of_expr)
# this doesn't work, i is undefined:
for i in range(1, length=length(array_of_expr))
result_array[i] = $(array_of_expr[i])
end
end
end
interpolate_1by1(test_input...)
有什么办法可以使这个工作吗?我已经尝试了引用的 SE 答案中的策略,但没有成功。
【问题讨论】:
标签: julia metaprogramming