使用julia中的表达式进行简单插值

时间:2017-08-15 23:06:11

标签: julia metaprogramming

我想形成像

这样的表达式
julia> ex = :(a[$myfunc(i,j),$j] + b[$i,$j])

因为我有兴趣编写一个程序,它能够编写一个方程组,其中用户只给出它们的结构,然后julia明确写出所涉及的代码块。更一般地说,我想在函数表中嵌入函数,比如

ERROR: UndefVarError: i not defined
 in eval(::Module, ::Any) at ./boot.jl:226

在评估第一行代码后,我得到了

julia> ex = :(a[i,j] + b[i,j])
:(a[i,j] + b[i,j])

julia> for i in 1:2
           for j in 1:2
               println(eval(ex))
           end
       end
ERROR: UndefVarError: i not defined
 in eval(::Module, ::Any) at ./boot.jl:226
 [inlined code] from ./boot.jl:225
 in anonymous at ./<no file>:4294967295
 in eval(::Module, ::Any) at ./boot.jl:226

另一方面,如果我写

{{1}}

在这种情况下如何进行插值?

1 个答案:

答案 0 :(得分:3)

eval适用于全局范围,因此无法引用任何局部变量。但是,您可以将该表达式插入到更大的代码块中,以便在全局范围内执行:

julia> a = [1 2; 3 4]
       b = [5 6; 7 8]
       ex = :(a[i,j] + b[i,j]);

julia> @eval for i in 1:2
                  for j in 1:2
                      println($ex)
                  end
              end
6
8
10
12

@eval宏是引用传递语法并将其传递给eval()函数的简单简写。定义自定义函数甚至可能更好:

julia> @eval function f()
              for i in 1:2
                  for j in 1:2
                      println($ex)
                  end
              end
       end
f (generic function with 1 method)

julia> f()
6
8
10
12

关于eval的常见警告适用:任何传递的代码都可以被恶意制作,以做出邪恶或令人惊讶的事情。或者只是让程序崩溃。