首页 > 解决方案 > 嵌套在 for 循环中的 if 块的 Julia 变量的范围

问题描述

for i=1:5
    if(i==1)
        z = i
    end
    println("i = $i, z = $z")
end

i = 1, z = 1
ERROR: UndefVarError: z not defined
Stacktrace:
 [1] top-level scope at ./REPL[6]:5 [inlined]
 [2] top-level scope at ./none:0

上述脚本的行为让我感到困惑。有人可以帮我理解为什么当 i=1 时打印有效,但当 i=2 时打印失败。

标签: julia

解决方案


@Wookies-Will-Code 的答案是正确的,这就是原因。

正如 Julia 手册在这里解释的那样:

for循环、while循环和理解具有以下行为:在其主体范围内引入的任何新变量都会为每次循环迭代重新分配

这意味着最后每次迭代z都会被遗忘。

为了确保在循环之前定义的值z在迭代(以及for循环完成之后)中是持久z的。例如像这样:

function mytest()
    local z
    for i=1:5
        if i==1
            z = i
        end
        println("i = $i, z = $z")
    end
end

现在你有:

julia> mytest()
i = 1, z = 1
i = 2, z = 1
i = 3, z = 1
i = 4, z = 1
i = 5, z = 1

请注意,在全球范围内情况有所不同。即使z是全局定义的,默认情况下也不会重用:

julia> z = 100
100

julia> for i=1:5
           if i==1
               z = i
           end
           println("i = $i, z = $z")
       end
i = 1, z = 1
ERROR: UndefVarError: z not defined
Stacktrace:
 [1] top-level scope at .\REPL[7]:5 [inlined]
 [2] top-level scope at .\none:0

原因是 Julia 将zfor 循环视为本地的,因为z被分配到循环内部。这是一个编译时功能检查,因此即使if条件总是失败,您也会收到此错误:

julia> z = 100
100

julia> for i=1:5
           if false
               z = i
           end
           println("i = $i, z = $z")
       end
ERROR: UndefVarError: z not defined
Stacktrace:
 [1] top-level scope at .\REPL[18]:5 [inlined]
 [2] top-level scope at .\none:0

您必须分配zusingglobal关键字才能使其工作:

julia> z = 100
100

julia> for i=1:5
           if i==1
               global z = i
           end
           println("i = $i, z = $z")
       end
i = 1, z = 1
i = 2, z = 1
i = 3, z = 1
i = 4, z = 1
i = 5, z = 1

推荐阅读