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

时间:2019-02-28 16:59:30

标签: 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时打印失败的原因。

2 个答案:

答案 0 :(得分:5)

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

如Julia手册所解释的here

  

for循环,while循环和Comprehensions具有以下行为:在其主体范围中引入的所有新变量都为每次循环迭代新鲜分配

这意味着最后每次迭代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将z视为for循环的本地对象,因为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

您必须使用z关键字将其分配给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

答案 1 :(得分:1)

我不使用茱莉亚,但是可以。我不确定如何发送未定义z的字符串,但是这里基于i的值有2种不同的prinln,这是最简单的实现方式,否则您必须检查是否定义了z,这比较简单。

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