【问题标题】:Scala, arrays always call by name, right?Scala,数组总是按名称调用,对吗?
【发布时间】:2012-11-19 19:56:08
【问题描述】:

在 Scala 中,数组总是按引用传递,按名称调用,对吗?

所以,

def fun(ar: Array[Int]) = {}

等于

def fun(ar: => Array[Int]) = {}

谢谢。

【问题讨论】:

  • 不,它们作为按值调用传递。是什么让你这么认为?
  • 因为,我有一个名为 fun(v) 的函数 def fun(ar: Array[Int]) = {} 能够修改数组 v。这可能是因为 scala 数组是Java 数组,以及 Java 中的对象是按名称调用的?
  • 在 java 中(以及在 scala 中),您通过引用传递所有 objects。您所做的只是传递 reference 的副本,然后使用它(您仍然可以到达内存中的同一对象并对其进行修改,因为引用指向内存中的同一位置)。
  • @om-nom-nom:不,您通过引用传递对象,无论是在 Scala 还是在 Java 中。 Java 总是按值传递。 Scala 是按值传递的,除了对应于名称参数的参数,它是按名称传递的(但也从不按引用传递)。更准确地说,您总是按值传递指向对象的指针,这有时也称为按对象共享或按共享调用。
  • @om-nom-nom: pass-by-reference 意味着被调用者可以在调用者的范围内修改变量。注意:我不是在谈论修改共享状态。如果调用者和被调用者都有一个指向同一个可变对象的指针,那么该对象的突变对两者都是可见的。但这只是共享的可变状态,与传递引用无关。引用传递意味着被调用者可以修改变量自身,而不仅仅是变量指向的对象。闭包实际上是在Scala中通过引用来捕获变量,在那里你可以看到效果。

标签: arrays scala pass-by-reference


【解决方案1】:

在 Scala 中,数组总是按引用传递,按名称调用,对吧?

没有。在 Scala 中,就像在 Java、C、C++(默认)、C#(默认)、Smalltalk、Ruby、Python 以及几乎所有其他已创建的面向对象语言中一样,参数是按值传递的。

可以显式声明一个按名称参数,然后(但只有这样)对应于该参数的参数将按名称传递。 Scala 将永远通过引用传递。

所以,

def fun(ar: Array[Int]) = {}

等于

def fun(ar: => Array[Int]) = {}

不,不是。在第一种情况下,数组(或者更确切地说是指向数组的指针)将按值传递,在第二种情况下按名称传递。在这两种情况下都不会通过引用传递。

【讨论】:

    【解决方案2】:

    为了进一步澄清,来自维基百科的以下quote 可能会有所帮助:

    但是,“共享通话”一词并不常用;不同来源的术语不一致。例如,在 Java 社区中,他们说 Java 是按值传递的,而在 Ruby 社区中,他们说 Ruby 是按引用传递的,尽管这两种语言表现出相同的语义。

    对于 C++ 程序员,恕我直言,在面对 Scala/Java 使用的术语时,有两点可能会导致混淆:

    • C++ 程序员将按值传递解释为“调用了复制构造函数”,这意味着调用者可以在不修改被调用者实例的情况下改变传递的对象。 Scala/Java 并非如此。当 Java 程序员 claims Java 是按值调用时,我总是将其翻译为“对象 references 是按值传递的”。
    • 对象的可能修改类似于 C++ 的引用参数(调用者对相同的实例进行操作)。从这个角度来看,我们可以得出结论,Scala 使用了引用调用。但是通过引用调用是由传递参数的可能重新分配定义的。这在 Scala 中是不可能的。由于评估策略既不是(类似 C++ 的)按值传递也不是按引用传递,我认为“按共享传递”一词最合适。

    【讨论】:

    • “引用”(在 Java 等中使用时)表示指向对象的指针。而且它们确实与 C++ 中指向对象的指针完全相似,具有完全类似于 C++ 的对象指针的按值传递语义。
    • 这正是很多混乱的根源:C++ 程序员故意区分“指向对象的指针”和“引用”,因为它们是不同的语言概念。当他说“将对象作为引用传递”时,他指的是按值传递对象引用。我只是想提及那个术语问题。
    • 我只是指出“对象的可能修改类似于 C++ 的引用参数”不是很正确。他们不像那样。传递 Java/Scala 完全 类似于 C++ 的对象指针。从这个角度来看,我们会得出结论,这是价值传递。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-01-01
    • 2016-05-12
    • 1970-01-01
    • 2021-09-11
    • 2018-06-26
    相关资源
    最近更新 更多