我正在使用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
Run Code Online (Sandbox Code Playgroud)
错误指向第16行。据我所知,这意味着在for循环范围内未定义etInt。朱莉娅为什么会这样?
据我了解,这意味着在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
Run Code Online (Sandbox Code Playgroud)
效果很好
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
Run Code Online (Sandbox Code Playgroud)
不起作用。可以通过放置显式global注释来治愈:
julia> for i in 1:3
global x += 1
@show x
end
x = 2
x = 3
x = 4
Run Code Online (Sandbox Code Playgroud)
请注意,人们对此抱怨很多,并且正在github和讨论中对此进行积极讨论(例如here和here)。
请注意,这些作用域规则的影响(例如,您收到的可能不直观的错误消息)实际上仅在全局范围内运行时才受到打击(例如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
Run Code Online (Sandbox Code Playgroud)
无论如何,这是您要真正获得快速运行时间应该采取的措施,因为全局变量几乎总是对性能不利(请参阅“ 性能提示”)。
还要注意,所有使用IJulia的Jupyter笔记本电脑都可以按预期工作。原因是人们也提出了上下文相关的解决方案,在本例中为SoftGlobalScope.jl。REPL正在/正在考虑类似的事情。这些是人们进行交互工作的主要场所。
因此,总而言之,您可以只学习作用域定义规则(这是非常简单的),也可以等待一些讨论过的“修复程序”着陆,就像Jupyter笔记本电脑一样。