定义变量时,Julia 会抛出未定义的错误
Julia throws undefined error when the variable is defined
我有一个使用 i = 1
作为索引的简单 while 循环。
global i = 1
n = rows
while i <= n
if prod(isa.(collect((y)[i,:]),Number))==0
delete!(y,i)
x_axis = x_axis[1:end .!= i]
n -= 1
end
i += 1
end
但我收到此错误:
UndefVarError: i not defined
top-level scope@Local: 23
我什至按照关于 SO 上一些类似问题的建议将我的 i 设为全局,但错误仍然存在。我在 Pluto.jl 上 运行,所以可能是环境问题。
首先,请注意,如果您使用 Julia v1.5+,那么您 不需要 将 i
设为全局(下面的示例使用当前稳定版本 v1 .5.4):
julia> i = 1
1
julia> while i < 5
println(i)
i += 1 # <----- this works in Julia v1.5+
end
1
2
3
4
但是,您似乎使用的是旧版本的 Julia v1.4,在这种情况下,我认为 Logan Kilpatrick 给了您答案:您需要从 inside[ 中将 i
设为全局变量 while
循环的作用域。正如 Logan 所提到的,尝试在增加 i
的地方添加 global
,就像 while
函数文档中的这个例子:
julia> i = 1 ;
julia> while i < 5
println(i)
global i += 1 # <------------ Try this!
end
1
2
3
4
另请注意,如果您的 while
循环在函数内部,您 不需要 指定它是全局的,如
julia> function foo(istart)
i = istart
while i < 5
println(i)
i += 1 # <-- 'global' not needed inside a function!
end
end
foo (generic function with 1 method)
julia> foo(1)
1
2
3
4
您遇到了“模棱两可的软范围案例”。
简而言之:局部变量在(软)局部范围内的赋值取决于代码是否在“REPL 上下文”中
与否。
例如,对于“REPL 上下文”,我指的是 REPL 和在这种情况下表现为 REPL 的所有环境
木星:
julia> i = 0
julia> while i < 3
i += 1
@info i
end
[ Info: 1
[ Info: 2
[ Info: 3
取而代之的是来自文件、eval 和 Pluto 等非交互式上下文的代码,其行为如下:
julia> code = """
i = 0
while i < 3
i += 1
@info i
end
"""
julia> include_string(Main, code)
┌ Warning: Assignment to `i` in soft scope is ambiguous because a global variable by the same name exists: `i` will be treated as a new local. Disambiguate by using `local i` to suppress this warning or `global i` to assign to the existing global variable.
└ @ string:3
ERROR: LoadError: UndefVarError: i not defined
所有这些都旨在确保 REPL 使用的便利性,并避免大规模使用 julia 带来的不良副作用。
完整详情here。
要解决此问题,您可以按照已建议的方式使用 global
或将您的代码包含在一个函数中。
Pluto 将单元格隐式包装到函数中,请参阅 https://github.com/fonsp/Pluto.jl/pull/720,因此不需要 global
注释或显式包装到函数中。
将以下内容放入 Pluto 单元格对我有用:
begin
i = 1
n = 100
while i<=n
if i % 2 == 0
n -= 1
end
i += 1
end
end
当在单元格内使用宏时,隐式函数包装被禁用(这会阻止 Pluto 收集反应性信息),因此由于 Julia 作用域规则,以下内容在 Pluto 中不起作用:
begin
i = 1
n = 100
while i<=n
if i % 2 == 0
n -= 1
end
@show i += 1
end
end
投掷:
UndefVarError: i not defined
top-level scope@Local: 5[inlined]
top-level scope@none:0
我有一个使用 i = 1
作为索引的简单 while 循环。
global i = 1
n = rows
while i <= n
if prod(isa.(collect((y)[i,:]),Number))==0
delete!(y,i)
x_axis = x_axis[1:end .!= i]
n -= 1
end
i += 1
end
但我收到此错误:
UndefVarError: i not defined
top-level scope@Local: 23
我什至按照关于 SO 上一些类似问题的建议将我的 i 设为全局,但错误仍然存在。我在 Pluto.jl 上 运行,所以可能是环境问题。
首先,请注意,如果您使用 Julia v1.5+,那么您 不需要 将 i
设为全局(下面的示例使用当前稳定版本 v1 .5.4):
julia> i = 1
1
julia> while i < 5
println(i)
i += 1 # <----- this works in Julia v1.5+
end
1
2
3
4
但是,您似乎使用的是旧版本的 Julia v1.4,在这种情况下,我认为 Logan Kilpatrick 给了您答案:您需要从 inside[ 中将 i
设为全局变量 while
循环的作用域。正如 Logan 所提到的,尝试在增加 i
的地方添加 global
,就像 while
函数文档中的这个例子:
julia> i = 1 ;
julia> while i < 5
println(i)
global i += 1 # <------------ Try this!
end
1
2
3
4
另请注意,如果您的 while
循环在函数内部,您 不需要 指定它是全局的,如
julia> function foo(istart)
i = istart
while i < 5
println(i)
i += 1 # <-- 'global' not needed inside a function!
end
end
foo (generic function with 1 method)
julia> foo(1)
1
2
3
4
您遇到了“模棱两可的软范围案例”。
简而言之:局部变量在(软)局部范围内的赋值取决于代码是否在“REPL 上下文”中 与否。
例如,对于“REPL 上下文”,我指的是 REPL 和在这种情况下表现为 REPL 的所有环境 木星:
julia> i = 0
julia> while i < 3
i += 1
@info i
end
[ Info: 1
[ Info: 2
[ Info: 3
取而代之的是来自文件、eval 和 Pluto 等非交互式上下文的代码,其行为如下:
julia> code = """
i = 0
while i < 3
i += 1
@info i
end
"""
julia> include_string(Main, code)
┌ Warning: Assignment to `i` in soft scope is ambiguous because a global variable by the same name exists: `i` will be treated as a new local. Disambiguate by using `local i` to suppress this warning or `global i` to assign to the existing global variable.
└ @ string:3
ERROR: LoadError: UndefVarError: i not defined
所有这些都旨在确保 REPL 使用的便利性,并避免大规模使用 julia 带来的不良副作用。
完整详情here。
要解决此问题,您可以按照已建议的方式使用 global
或将您的代码包含在一个函数中。
Pluto 将单元格隐式包装到函数中,请参阅 https://github.com/fonsp/Pluto.jl/pull/720,因此不需要 global
注释或显式包装到函数中。
将以下内容放入 Pluto 单元格对我有用:
begin
i = 1
n = 100
while i<=n
if i % 2 == 0
n -= 1
end
i += 1
end
end
当在单元格内使用宏时,隐式函数包装被禁用(这会阻止 Pluto 收集反应性信息),因此由于 Julia 作用域规则,以下内容在 Pluto 中不起作用:
begin
i = 1
n = 100
while i<=n
if i % 2 == 0
n -= 1
end
@show i += 1
end
end
投掷:
UndefVarError: i not defined
top-level scope@Local: 5[inlined]
top-level scope@none:0