在 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 设为字典时,会观察到类似的行为。
三个问题
- 变量/数组的这种行为及其在函数内的作用域是否与 Julia 的工作方式一致?
- 当 x 是一个数组时,即使不将引用作为函数的输入传递,它在函数内部也是可见的。这是正确的吗?
- 此外,更改数组中条目的值会全局反映。这是因为 Julia 到处都将数组 x 视为引用吗?
让我评论一下我对这个问题的理解。
首先,变量名指向值。在变量名和值之间建立绑定的最基本方法是赋值形式:
variable_name = value
请注意,在 =
的左侧,唯一存在的是变量名,没有其他内容,这一点很重要。
(旁注:除了 =
之外,还有其他方法可以进行绑定,例如 +=
等或函数定义;但让我们在这里关注问题的核心)
现在,如果您看到 =
,这并不意味着它是创建新绑定的赋值。特别是:
variable_name[index] = value
不是赋值操作(创建新绑定)而是 setindex!
操作。写成 variable_name[index] = value
等同于写成 setindex!(variable_name, value, index
.
(旁注:除了一些极端情况,例如 begin
或 end
的处理,@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
)。
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 设为字典时,会观察到类似的行为。
三个问题
- 变量/数组的这种行为及其在函数内的作用域是否与 Julia 的工作方式一致?
- 当 x 是一个数组时,即使不将引用作为函数的输入传递,它在函数内部也是可见的。这是正确的吗?
- 此外,更改数组中条目的值会全局反映。这是因为 Julia 到处都将数组 x 视为引用吗?
让我评论一下我对这个问题的理解。
首先,变量名指向值。在变量名和值之间建立绑定的最基本方法是赋值形式:
variable_name = value
请注意,在 =
的左侧,唯一存在的是变量名,没有其他内容,这一点很重要。
(旁注:除了 =
之外,还有其他方法可以进行绑定,例如 +=
等或函数定义;但让我们在这里关注问题的核心)
现在,如果您看到 =
,这并不意味着它是创建新绑定的赋值。特别是:
variable_name[index] = value
不是赋值操作(创建新绑定)而是 setindex!
操作。写成 variable_name[index] = value
等同于写成 setindex!(variable_name, value, index
.
(旁注:除了一些极端情况,例如 begin
或 end
的处理,@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
)。