我从这里知道:
Julia 函数参数遵循有时称为“传递共享”的约定,这意味着值在传递给函数时不会被复制。函数参数本身充当新的变量绑定(可以引用值的新位置),但它们引用的值与传递的值相同。在函数中对可变值(例如数组)所做的修改对调用者是可见的。这与 Scheme、大多数 Lisps、Python、Ruby 和 Perl 以及其他动态语言中的行为相同。
鉴于此,我很清楚要通过引用传递,您需要做的就是将可变类型传递给函数并进行编辑。
那么我的问题就变成了,我如何清楚地区分传值和传引用?有没有人有一个例子显示一个函数被调用了两次?一次是按引用传递,一次是按值传递?
我看到这篇文章暗示了一些类似的想法,但它没有完全回答我的问题。
在 Julia 中,函数总是具有传递共享参数传递行为:
https://docs.julialang.org/en/v1/manual/functions/
这种参数传递约定也用于大多数通用动态编程语言,包括各种 Lisps、Python、Perl 和 Ruby。可以在此处找到一个很好且有用的描述:
https://en.wikipedia.org/wiki/Evaluation_strategy#Call_by_sharing
简而言之,共享传递的工作方式类似于引用传递,但您不能通过重新分配给被调用函数中的参数来更改调用范围中的绑定所引用的值——如果您重新分配一个参数,则来电者不变。这意味着通常您不能使用函数来更改绑定,例如交换到变量。(然而,宏可以修改调用者中的绑定。)特别是,如果调用者中的变量引用一个不可变值,如整数或浮点数,则其值不能被函数调用更改,因为哪个对象是变量引用不能被函数调用更改,并且值本身不能修改,因为它是不可变的。
如果您想拥有 R 或 Matlab 之类的按值传递行为,则需要在修改参数之前显式创建参数的副本。这正是 R 和 Matlab 所做的,当一个参数被传递到一个被修改的参数并且一个对该参数的外部引用仍然存在时。在 Julia 中,它必须由程序员显式完成,而不是由系统自动完成。一个缺点是,当程序员通常不知道这一点时,系统有时可以知道不需要副本(没有外部引用)。然而,这种能力与引用计数垃圾收集技术密切相关,由于性能方面的考虑,Julia 没有使用这种技术。
按照惯例,改变参数内容的函数有一个!后缀(例如,sortv/s sort!)。