在 Julia 中的函数内重新分配字典值

Reassignment of Dictionary Values inside a Function in Julia

Julia 的新手,因此可能是一个基本问题。

x = 1
function someFn()
   print(x)
   x = 3 
end

这会在 print(x) 处引发错误,因为函数内部看不到全局 x。这是有道理的。

x = [1,2]
function someFn()
   print(x)
   x[1] = 4
end
print(x)

此处 print(x) 能够看到全局数组 x 并且 x[1]=4 全局更改全局 x 的值。当我将 x 设为字典时,会观察到类似的行为。

三个问题

  1. 变量/数组的这种行为及其在函数内的作用域是否与 Julia 的工作方式一致?
  2. 当 x 是一个数组时,即使不将引用作为函数的输入传递,它在函数内部也是可见的。这是正确的吗?
  3. 此外,更改数组中条目的值会全局反映。这是因为 Julia 到处都将数组 x 视为引用吗?

让我评论一下我对这个问题的理解。

首先,变量名指向值。在变量名和值之间建立绑定的最基本方法是赋值形式:

variable_name = value

请注意,在 = 的左侧,唯一存在的是变量名,没有其他内容,这一点很重要。

(旁注:除了 = 之外,还有其他方法可以进行绑定,例如 += 等或函数定义;但让我们在这里关注问题的核心)

现在,如果您看到 =,这并不意味着它是创建新绑定的赋值。特别是:

variable_name[index] = value

不是赋值操作(创建新绑定)而是 setindex! 操作。写成 variable_name[index] = value 等同于写成 setindex!(variable_name, value, index.

(旁注:除了一些极端情况,例如 beginend 的处理,@view 宏处理等,这是正确的,但这同样不是关键在讨论中)

现在根据这些评论直接回答您的问题:

Is this behavior of variable / array and its scope inside a function consistent how Julia should work?

是的。但请注意,您在以下位置遇到错误:

x = 1
function someFn()
   print(x)
   x = 3 
end

因为 Julia 知道 x = 3 出现在函数体中,这让 Julia 知道 x 是一个局部变量,甚至在它绑定到值之前(一个变量是局部变量或全球)。

这里有一个更极端的例子:

julia> x = 10
10

julia> function f()
       if true
           println(x)
       else
           x = 5
       end
       end
f (generic function with 1 method)

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

尽管我们知道 else 之后的分支永远不会执行,但它仍然使变量 x 成为本地变量。

When x is an array, it is visible inside the function even without passing a reference as an input to function. Is this correct?

它是可见的,因为 x[1] = 4 没有创建名为 x 的局部变量,而只是对 setindex! 函数的调用。所以没有在本地定义 x 变量,因此使用全局变量 x

Also, changing a value of an entry in the array is reflected globally. Is this so because Julia treats array x as a reference everywhere?

这里一定要记住x不是数组。它是一个绑定指向数组的变量。然后,x[1] = 4 与您编写 setindex!(x, 4, 1) 相同,因此您只需在变量 x 绑定到的值(在本例中为数组)上调用函数。这是可行的,因为 Julia 中的范围规则规定,如果范围内没有给定名称的局部变量,Julia 会在全局范围内搜索该名称。

最后让我评论一下,不鼓励在 Julia 中使用全局变量,因为这很慢。因此,虽然这个讨论与理解 Julia 的工作原理高度相关,但在实践中你几乎不需要知道这一点(你将在 99.99% 的时间使用局部变量,如果你使用全局变量更好地使它们 const)。