Julia 范围:为什么这个函数会修改一个全局变量?

Lev*_*sco 3 arguments function scoping julia

我是 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
Run Code Online (Sandbox Code Playgroud)

但是当对数组做类似的事情时,它充当一个变异函数(在全局范围内修改它的参数!)

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
Run Code Online (Sandbox Code Playgroud)

我意识到我可以通过将第一行更改为 来解决这个问题y = copy(x),但是首先出现这种(危险的?)行为的原因是什么?

Nil*_*dat 7

我会为此写一个答案,但我认为 John Myles White 已经做得比我以往任何时候都好,所以我将链接到他的博文:

https://www.juliabloggers.com/values-vs-bindings-the-map-is-not-the-territory-3/

总之x = 1x[1] = 1是非常不同的操作。第一个是赋值——即改变变量的绑定x——而第二个是调用setindex!函数的语法糖,在数组的情况下,它分配给数组中的一个位置。赋值只更改哪些变量引用哪些对象,而不会修改任何对象。Mutation 只会修改对象,而不会改变哪些变量指向哪些对象。这个答案有更多关于区别的细节:Creating Copy in Julia with = operator

  • 简而言之,“x = 1”和“x[1] = 1”是非常不同的操作。第一个是赋值(更改“x”的绑定),而第二个是“setproperty!”函数的语法糖。 (3认同)