3

我已经阅读了Scala 中方法和函数之间的差异问题以及许多关于方法和函数之间差异的文章。我有一种感觉,“方法”只是一个“命名函数”,定义为类、特征或对象中的方法。“函数”代表那些文章中的“匿名函数”或“函数文字”或“函数对象”之类的东西。可以在《Scala 编程》一书 http://www.artima.com/shop/programming_in_scala_2ed中找到证据,第 141 页,第 8.1 节,“定义函数的最常见方法是作为某个对象的成员。这样的函数称为方法。”

但是,当我检查 Scala 语言参考http://www.scala-lang.org/docu/files/ScalaReference.pdf时,有一些概念,如命名方法。在第 91 页,第 6.20 节返回表达式:“返回表达式 return e 必须出现在某些封闭的命名方法或函数的主体内。” 您还可以在同一页面和其他地方找到术语“命名函数”。

所以我的问题是,在 Scala 中,方法、命名方法和命名函数是指同一个概念吗?你从哪里得到命名函数的定义?

在代码List(1, 2).map(_ + 1)中,原始表达式_ + 1是一个命名方法,然后将方法转换为函数。什么样的函数,匿名函数,函数对象,命名函数?

在我的理解中,Scala 只有两种类型的函数:命名函数是一个方法;一个匿名函数,它是一个函数文字。函数字面量被编译成 trait FunctionN 的函数对象,以便在 Scala 的纯面向对象世界中使用。

但是,对于上面代码中的常规命名函数/方法_ + 1,为什么 Scala 将其转换为另一个函数对象?

4

2 回答 2

7

在语言层面,只有两个概念,

  • 方法是 Scala 的基本构建块。方法总是被命名的。方法存在于类或特征中。方法是 JVM 原生的构造,因此在 Scala 和 Java 中是相同的。Scala 中的方法(与函数不同)可能具有特殊功能:它们可以通过类型参数进行抽象,它们的参数可以具有默认值或隐式等。

  • 函数对象只是函数 trait ( Function1, Function2, ...) 的实例。当apply函数对象上的方法被调用时,函数会被计算。定义未命名的“匿名”函数(又名“函数文字”)有特殊语法。函数只是一个值,因此可以命名(例如,val f: (Int => Int) = (x => x))。类型A => B是 的简写Function1[A, B]

链接的 SO question中,有人提到某些参考文献(如 Scala 规范)不精确地使用“函数”一词来表示“方法”或“函数对象”。我猜部分原因是方法可以根据上下文自动转换为函数对象。但是请注意,相反的转换是没有意义的:方法不是存在于堆上且独立存在的一流值。相反,一个方法与定义它的类有着千丝万缕的联系。

于 2011-09-08T06:40:52.447 回答
7

链接问题的答案很好地涵盖了这一点,但要解决您的具体问题:

  • 方法 => 你用def关键字定义的东西
  • 命名方法 => 相同,所有方法都有名称
  • 命名函数 => 已分配给值或从方法转换的函数。与匿名函数相比。

方法和函数之间的区别有点像Java 中的int基元和装箱之间的区别。Integer

在一般性讨论中,通常听到两者都被描述为“整数”。这通常不是问题,但是您必须注意在与区别相关的地方保持精确

同样,当您的程序需要时,方法将自动转换为函数(因此也是对象),就像装箱原语一样。因此,将方法称为函数并不是完全错误的。

更新

那么它是怎样工作的?

当您尝试将方法作为参数传递给 egList[A].map时,编译器将生成派生的内部类(具有合成名称)Function1[A,B]apply委托给您最初提供的方法的方法。然后这个实例将作为实际参数传递。

于 2011-09-08T06:45:57.867 回答