为什么Julia变量在for循环范围内不存在?

时间:2019-01-27 02:30:52

标签: julia

我正在使用Julia进行一些基本的集成估算,并使用以下代码获取UndefVarError:

using ExcelReaders
er = ExcelReaders

etInt = 0

waveLen = er.readxl("AM0AM1_5.xls", "Spectra!A3:A2004")
eT = er.readxl("AM0AM1_5.xls", "Spectra!B3:B2004")
gTilt = er.readxl("AM0AM1_5.xls", "Spectra!C3:C2004")
dirSol = er.readxl("AM0AM1_5.xls", "Spectra!D3:D2004")  

function trArea(r::Real, l::Real, v::Array, x::Int)
    return ((1/2) * (v[x] + v[x+1]) * (r-l))
end

for x in 1:length(waveLen)-1
    etInt += trArea(waveLen[x], waveLen[x+1], eT, x)
end

错误指向第16行。据我所知,这意味着在for循环范围内未定义etInt。朱莉娅为什么会这样?

2 个答案:

答案 0 :(得分:4)

  

据我了解,这意味着在for循环范围内未定义etInt。

全局变量确实存在于所有局部作用域(例如for循环)中。但是,从Julia版本1.0开始,它们在这些本地范围中是只读的。必须对全局变量进行写访问。

举一个简单的例子,

julia> x = 1       
1                  

julia> for i in 1:3
           @show x # only reading a global variable
       end         
x = 1              
x = 1              
x = 1              

工作正常,

julia> for i in 1:3
           x += 1 # writing to a global variable
           @show x
       end
ERROR: UndefVarError: x not defined
Stacktrace:
 [1] top-level scope at .\REPL[3]:2 [inlined]
 [2] top-level scope at .\none:0

不起作用。可以通过放置显式global注释来治愈:

julia> for i in 1:3
           global x += 1
           @show x
       end
x = 2
x = 3
x = 4

有关更多信息,请参见scoping section in the Julia documentation

请注意,人们对此抱怨很多,并且正在github和话语(例如herehere)上对此进行积极讨论。

请注意,这些作用域规则的影响(例如,您收到的可能不直观的错误消息)实际上仅在全局范围内运行时才受到打击(例如REPL)。如果将所有内容放到一个函数中-任何局部作用域-您都会得到预期的行为:

julia> function f()
           x = 1
           for i in 1:3
               x += 1 # no global necessary
               @show x
           end
           nothing
       end
f (generic function with 1 method)

julia> f()
x = 2
x = 3
x = 4

无论如何,这是您要真正获得快速运行时间的方法,因为全局变量几乎总是对性能不利(请参见Performance Tips)。

还请注意,所有使用IJulia的Jupyter笔记本电脑都可以正常工作。原因是人们也在想出上下文相关的解决方案,在这种情况下为SoftGlobalScope.jl。 REPL正在/正在考虑类似的事情。这些是人们进行交互工作的主要场所。

因此,总而言之,您可以只学习作用域定义规则(这很简单),也可以等待一些讨论过的“修复程序”登陆,就像jupyter笔记本电脑一样。

答案 1 :(得分:3)

似乎在1.0中实现了范围更改,这在REPL和笔记本的上下文中影响了Julia中的此行为。其他一些用户对此有所抱怨,例如

https://discourse.julialang.org/t/undefvarerror-on-loop-iterator-in-while-loop/14747 https://github.com/JuliaLang/julia/issues/28789

似乎已提出纠正这一怪异的提议:

https://discourse.julialang.org/t/new-scope-solution/16707/