如何在Julia中评估局部变量

Sea*_*sey 10 julia

i = 50
function test()
  i = 10
  eval(:i)
end
test()  # => 50
Run Code Online (Sandbox Code Playgroud)

为什么这会评估全局i而不是本地?有没有办法让它评估到当地?

Ste*_*ski 9

你不能.Julia eval总是评估代码当前模块的范围,而不是本地范围.eval在运行时调用是一种反模式和性能杀手.

  • 我扩展了我的答案以改进它。感谢您提示我这样做,原来的答案太简洁而且没有太大帮助。希望这会更好。 (3认同)
  • 我不断看到人们这么说(也在 JavaScript 社区中)。我编写了很多开发工具,例如在运行时评估用户代码的代码,并且尽我所能,我无法弄清楚如何在运行时不使用 eval 来完成这些事情。我还向 JavaCall 贡献了代码,该代码在运行时使用 eval 结合 Java 在运行时的自省来生成调用 Java 的函数,但我看不出在运行时不使用 eval 的好方法。也许我错过了一些东西,但“运行时评估是一种反模式”的笼统声明对我来说似乎没有根据。 (2认同)

Rez*_*lan 6

正如@StefanKarpinski提到的那样,eval总是在全局范围内进行评估,但是如果您真的想在本地进行评估,则可以通过多种方式进行:

import Base.Cartesian.lreplace
i = 50
function test1(expr)
  i=10
  eval(lreplace(expr,:i,i))
end

i = 50
function test2()
  i = 10
  @eval $i
end
test1(:(i))  # => 10
test2()      # => 10
Run Code Online (Sandbox Code Playgroud)

但是我在运行时评估表达式的首选方法是创建一个函数,我认为这是最有效的:

exprtoeval=:(x*x)
@eval f(x)=$exprtoeval
f(4) # => 16
Run Code Online (Sandbox Code Playgroud)