我读过Scala函数(Scala另一个指南的一部分)。在那篇帖子中,他说:

方法和函数不是一回事

但他什么也没解释。他到底想说什么?


当前回答

方法属于一个对象(通常是定义它的类、trait或对象),而函数本身是一个值,因为在Scala中每个值都是一个对象,因此,函数是一个对象。

例如,给定下面的方法和函数:

def timesTwoMethod(x :Int): Int = x * 2
def timesTwoFunction = (x: Int) => x * 2

第二个def是Int => Int类型的对象(Function1[Int, Int]的语法糖)。

Scala将函数作为对象,这样它们就可以作为一级实体使用。通过这种方式,可以将函数作为参数传递给其他函数。

然而,Scala也可以通过一种称为Eta展开的机制将方法视为函数。

例如,定义在List上的高阶函数映射,接收另一个函数f: A => B作为其唯一参数。接下来的两行是等价的:

List(1, 2, 3).map(timesTwoMethod)
List(1, 2, 3).map(timesTwoFunction)

当编译器在需要函数的地方看到def时,它会自动将该方法转换为等效的函数。

其他回答

在Scala 2.13中,与函数不同,方法可以接受/返回

类型参数(多态方法) 隐式参数 从属类型

然而,这些限制在dotty (Scala 3)中通过多态函数类型#4672解除了,例如,dotty版本0.23.0-RC1支持以下语法

类型参数

def fmet[T](x: List[T]) = x.map(e => (e, e))
val ffun = [T] => (x: List[T]) => x.map(e => (e, e))

隐式参数(上下文参数)

def gmet[T](implicit num: Numeric[T]): T = num.zero
val gfun: [T] => Numeric[T] ?=> T = [T] => (using num: Numeric[T]) => num.zero

从属类型

class A { class B }
def hmet(a: A): a.B = new a.B
val hfun: (a: A) => a.B = hmet

更多示例请参见tests/run/ polymorphism -functions.scala

函数不支持默认参数。做的方法。从方法转换到函数会丢失参数默认值。(Scala 2.8.1发布)

区别是细微的,但却是实质性的,它与所使用的类型系统有关(除了来自面向对象或函数范式的术语)。

当我们谈论函数时,我们谈论的是函数类型:它是一种类型,它的实例可以作为输入或输出传递给其他函数(至少在Scala中是这样)。

当我们谈论(类的)方法时,我们实际上是在谈论它所属的类所表示的类型:也就是说,方法只是更大类型的一个组件,不能单独传递。它必须与它所属类型的实例(即类的实例)一起传递。

方法属于一个对象(通常是定义它的类、trait或对象),而函数本身是一个值,因为在Scala中每个值都是一个对象,因此,函数是一个对象。

例如,给定下面的方法和函数:

def timesTwoMethod(x :Int): Int = x * 2
def timesTwoFunction = (x: Int) => x * 2

第二个def是Int => Int类型的对象(Function1[Int, Int]的语法糖)。

Scala将函数作为对象,这样它们就可以作为一级实体使用。通过这种方式,可以将函数作为参数传递给其他函数。

然而,Scala也可以通过一种称为Eta展开的机制将方法视为函数。

例如,定义在List上的高阶函数映射,接收另一个函数f: A => B作为其唯一参数。接下来的两行是等价的:

List(1, 2, 3).map(timesTwoMethod)
List(1, 2, 3).map(timesTwoFunction)

当编译器在需要函数的地方看到def时,它会自动将该方法转换为等效的函数。

function A function can be invoked with a list of arguments to produce a result. A function has a parameter list, a body, and a result type. Functions that are members of a class, trait, or singleton object are called methods. Functions defined inside other functions are called local functions. Functions with the result type of Unit are called procedures. Anonymous functions in source code are called function literals. At run time, function literals are instantiated into objects called function values.

Scala第二版编程。 马丁·奥德斯基,莱克斯·斯彭,比尔·凡纳斯