首页 > 解决方案 > 在 julia 中声明和更改变量值的问题

问题描述

我的代码有什么问题?我必须x在使用前声明吗?

function f(n::Int64, t::Int64)
A = ones(n,n)
for i=0:t
    if i > 0
        A[x,a] = rand()*A[x,a] + rand()
    end
    y = rand(1:n)
    b = rand(1:n)
    if i > 0
        A[x,a] = rand()*A[x,a] + rand()*A[y,b]
    end
    x = y
    a = min(b, rand(1:n))
end
return A
end

这是尝试调用时引发的错误f

UndefVarError: x 未定义

标签: julia

解决方案


我认为原因更复杂,因为 Python 中的类似代码会起作用。

例如比较(Python):

>>> def f():
...     for i in range(3):
...         if i > 0:
...             print(a)
...         a = i
...
>>> f()
0
1

给(朱莉娅):

julia> function f()
           for i in 0:2
               if i > 0
                   println(a)
               end
               a = i
           end
       end
f (generic function with 1 method)

julia> f()
ERROR: UndefVarError: a not defined

那么区别是什么呢?正如 Julia 手册在这里解释的那样,你有:

for循环、while循环和推导具有以下行为:在其主体范围内引入的任何新变量都为每次循环迭代重新分配,就好像循环体被一个let块包围

这意味着在您的代码变量中ax由于它们是循环的本地变量,因此在for循环的每次迭代中都是新分配的。因此,必须在循环内访问变量之前对其进行分配。

因此,不需要在循环之前和之前分配值。xa在循环外部的范围内定义它们就足够了(即使没有分配值)。例如像这样:

julia> function f(n::Int64, t::Int64)
           A = ones(n,n)
           local x, a
           for i=0:t
               if i > 0
                   A[x,a] = rand()*A[x,a] + rand()
               end
               y = rand(1:n)
               b = rand(1:n)
               if i > 0
                   A[x,a] = rand()*A[x,a] + rand()*A[y,b]
               end
               x = y
               a = min(b, rand(1:n))
           end
           return A
       end
f (generic function with 1 method)

julia> f(1,1)
1×1 Array{Float64,2}:
 0.94526289614139

现在它可以工作了,因为x并且a没有在循环的每次迭代中新分配。

在我原来的玩具示例中,它看起来像:

julia> function f()
           local a
           for i in 0:2
               if i > 0
                   println(a)
               end
               a = i
           end
       end
f (generic function with 2 methods)

julia> f()
0
1

你会看到你得到的正是你在 Python 中所拥有的。


推荐阅读