Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/wcf/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何在Julia中计算局部变量_Julia - Fatal编程技术网

如何在Julia中计算局部变量

如何在Julia中计算局部变量,julia,Julia,为什么该值计算为全局i,而不是本地值?有没有办法让它在当地进行评估?你不能。Julia的eval总是对当前模块的作用域而不是本地作用域进行代码计算。在本地范围内调用eval是一种反模式和性能杀手。但是,您可以构造一个新函数,其中包含一点引用本地范围的用户代码,然后调用该函数。例如: i = 50 function test() i = 10 eval(:i) end test() # => 50 现在您可以调用test: # user-supplied expression e

为什么该值计算为全局
i
,而不是本地值?有没有办法让它在当地进行评估?

你不能。Julia的
eval
总是对当前模块的作用域而不是本地作用域进行代码计算。在本地范围内调用
eval
是一种反模式和性能杀手。但是,您可以构造一个新函数,其中包含一点引用本地范围的用户代码,然后调用该函数。例如:

i = 50
function test()
  i = 10
  eval(:i)
end
test()  # => 50
现在您可以调用
test

# user-supplied expression
expr = :(i^2 + 1)

# splice into function body
test = @eval function ()
    i = 10
    $expr
end

为什么这比在问题中调用
test
内部调用
eval
要好?因为在最初的用法中,
eval
需要在每次调用
test
时调用,而在这种用法中,
eval
在定义
test
时只调用一次;调用
test
时,不执行
eval
。因此,虽然您可以调用
eval
“在运行时”,意思是“当您的应用程序正在运行时,获取用户输入”,但在调用使用该用户输入构造的函数时,它不会被称为“在运行时”。前者很好,而后者显然是一种反模式。

根据应用程序,您可以
eval
整个函数以获得
i
的局部值,如@simonster在中所述。

如@StefanKarpinski所述
eval
始终在全局范围内计算,但如果一个人真的想在当地评估某件事,有多种方法:

julia> test()
101
但我更喜欢在运行时计算表达式的方法是创建函数,我认为这是最有效的方法:

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

我一直看到人们这样说(在JavaScript社区也是如此)。我编写了很多开发工具,比如在运行时评估用户代码的代码,并尽可能地尝试,如果不在运行时使用eval,我就无法理解如何做这些事情。我还为JavaCall提供了代码,该代码在运行时使用eval,并结合Java在运行时的内省来生成调用Java的函数,如果不在运行时使用eval,我看不到一个好方法。也许我遗漏了一些东西,但“运行时评估是一种反模式”的笼统说法对我来说似乎毫无根据。我已经扩展了我的答案以改进它。谢谢你提醒我这么做,原来的答案太简洁了,没有多大帮助。希望这样更好。
exprtoeval=:(x*x)
@eval f(x)=$exprtoeval
f(4) # => 16