2

我有这个简单的while循环i = 1用作索引。

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 上运行它,所以可能是环境问题。

4

3 回答 3

1

首先,请注意,如果您使用 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 给了您答案:您需要在循环范围i创建一个全局变量。正如 Logan 提到的,尝试添加where you increment ,就像函数文档中的这个例子一样:whileglobaliwhile

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
于 2021-03-22T09:13:25.687 回答
0

您遇到了“模棱两可的软范围案例”。

简而言之:在(软)局部范围内分配局部变量取决于代码是否在“REPL 上下文”中。

对于“REPL 上下文”,我指的是 REPL 以及在这种情况下表现为 REPL 的所有环境,例如 Jupyter:

julia> i = 0
julia> while i < 3
         i += 1
         @info i
       end
[ Info: 1
[ Info: 2
[ Info: 3

相反,来自非交互式上下文(如 file、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 的副作用。

完整的细节在这里

要解决问题,您可以global按照已经建议的方式使用或将您的代码包含在函数中。

于 2021-03-22T10:35:59.840 回答
0

Pluto 隐式地将一个单元格包装到一个函数中,请参阅https://github.com/fonsp/Pluto.jl/pull/720,因此global不需要注释或显式包装到一个函数中。

将以下内容放入冥王星细胞对我有用:

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
于 2021-03-24T16:08:33.480 回答