Julia 作用域:为什么这个函数要修改一个全局变量?
Julia scoping: why does this function modify a global variable?
我是 Julia 的新手,到目前为止我是它的粉丝。但是经过多年的 R 编程,一些范围规则让我感到困惑。
让我们来看看这个函数。这完全符合我的预期。
function foo1(x)
y = x
t = 1
while t < 1000
t += 1
y += 1
end
return 42
end
var = 0;
foo1(var)
# 42
var
# 0
但是当在数组上做类似的事情时,它充当一个变异函数(在全局范围内修改它的参数!)
function foo2(x)
y = x
t = 1
while t < 1000
t += 1
y[1] += 1
end
return 42
end
var = zeros(1);
foo2(var)
# 42
var
# 999.0
我知道我可以通过将第一行更改为 y = copy(x)
来解决这个问题,但是首先出现这种(危险的?)行为的原因是什么?
我会写一个答案,但我认为 John Myles White 已经比我做得更好,所以我会 link 他的博文:
https://www.juliabloggers.com/values-vs-bindings-the-map-is-not-the-territory-3/
简而言之x = 1
和x[1] = 1
是非常不同的操作。第一个是赋值——即改变变量 x
的绑定——而第二个是调用 setindex!
函数的语法糖,在数组的情况下,它分配给数组中的一个位置。赋值只会改变哪些变量引用哪些对象,而不会修改任何对象。变异只会修改对象,而不会改变哪些变量引用哪些对象。这个答案有更多关于区别的细节:.
我是 Julia 的新手,到目前为止我是它的粉丝。但是经过多年的 R 编程,一些范围规则让我感到困惑。
让我们来看看这个函数。这完全符合我的预期。
function foo1(x)
y = x
t = 1
while t < 1000
t += 1
y += 1
end
return 42
end
var = 0;
foo1(var)
# 42
var
# 0
但是当在数组上做类似的事情时,它充当一个变异函数(在全局范围内修改它的参数!)
function foo2(x)
y = x
t = 1
while t < 1000
t += 1
y[1] += 1
end
return 42
end
var = zeros(1);
foo2(var)
# 42
var
# 999.0
我知道我可以通过将第一行更改为 y = copy(x)
来解决这个问题,但是首先出现这种(危险的?)行为的原因是什么?
我会写一个答案,但我认为 John Myles White 已经比我做得更好,所以我会 link 他的博文:
https://www.juliabloggers.com/values-vs-bindings-the-map-is-not-the-territory-3/
简而言之x = 1
和x[1] = 1
是非常不同的操作。第一个是赋值——即改变变量 x
的绑定——而第二个是调用 setindex!
函数的语法糖,在数组的情况下,它分配给数组中的一个位置。赋值只会改变哪些变量引用哪些对象,而不会修改任何对象。变异只会修改对象,而不会改变哪些变量引用哪些对象。这个答案有更多关于区别的细节: