我读过Scala函数(Scala另一个指南的一部分)。在那篇帖子中,他说:
方法和函数不是一回事
但他什么也没解释。他到底想说什么?
我读过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时,它会自动将该方法转换为等效的函数。
其他回答
方法属于一个对象(通常是定义它的类、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时,它会自动将该方法转换为等效的函数。
方法和函数之间一个很大的实际区别是返回的含义。Return只从一个方法返回。例如:
scala> val f = () => { return "test" }
<console>:4: error: return outside method definition
val f = () => { return "test" }
^
从方法中定义的函数返回一个非局部返回:
scala> def f: String = {
| val g = () => { return "test" }
| g()
| "not this"
| }
f: String
scala> f
res4: String = test
而从局部方法返回只从该方法返回。
scala> def f2: String = {
| def g(): String = { return "test" }
| g()
| "is this"
| }
f2: String
scala> f2
res5: String = is this
在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和c++都有函数,但在JAVA中,你必须用静态方法来模仿它们。
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第二版编程。 马丁·奥德斯基,莱克斯·斯彭,比尔·凡纳斯