Julia变量的范围以及if块嵌套在for循环中

Roh*_*ndo 5 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
Run Code Online (Sandbox Code Playgroud)

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

Bog*_*ski 5

@ 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
Run Code Online (Sandbox Code Playgroud)

现在您有:

julia> mytest()
i = 1, z = 1
i = 2, z = 1
i = 3, z = 1
i = 4, z = 1
i = 5, z = 1
Run Code Online (Sandbox Code Playgroud)

请注意,全球范围内的情况有所不同。即使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
Run Code Online (Sandbox Code Playgroud)

原因是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
Run Code Online (Sandbox Code Playgroud)

您必须分配给zusing global关键字才能使其正常工作:

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
Run Code Online (Sandbox Code Playgroud)