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

方法和函数不是一回事

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


当前回答

实际上,Scala程序员只需要知道以下三条规则就可以正确使用函数和方法:

由def定义的方法和由=>定义的函数字面量是函数。在《Programming in Scala》第4版第8章第143页中定义。 函数值是可以作为任何值传递的对象。函数字面量和部分应用的函数是函数值。 如果在代码中的某个位置需要函数值,则可以省略部分应用的函数的下划线。例如:someNumber.foreach(println)

在《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程序员只需要知道以下三条规则就可以正确使用函数和方法:

由def定义的方法和由=>定义的函数字面量是函数。在《Programming in Scala》第4版第8章第143页中定义。 函数值是可以作为任何值传递的对象。函数字面量和部分应用的函数是函数值。 如果在代码中的某个位置需要函数值,则可以省略部分应用的函数的下划线。例如:someNumber.foreach(println)

在《Scala编程》发行了四个版本之后,区分函数和函数值这两个重要概念仍然是个问题,因为所有版本都没有给出明确的解释。语言规范太复杂了。我发现上面的规则既简单又准确。

假设你有一个列表

scala> val x =List.range(10,20)
x: List[Int] = List(10, 11, 12, 13, 14, 15, 16, 17, 18, 19)

定义一个方法

scala> def m1(i:Int)=i+2
m1: (i: Int)Int

定义一个函数

scala> (i:Int)=>i+2
res0: Int => Int = <function1>

scala> x.map((x)=>x+2)
res2: List[Int] = List(12, 13, 14, 15, 16, 17, 18, 19, 20, 21)

接受参数的方法

scala> m1(2)
res3: Int = 4

用val定义函数

scala> val p =(i:Int)=>i+2
p: Int => Int = <function1>

函数的参数是可选的

 scala> p(2)
    res4: Int = 4

scala> p
res5: Int => Int = <function1>

方法的参数是强制的

scala> m1
<console>:9: error: missing arguments for method m1;
follow this method with `_' if you want to treat it as a partially applied function

查看下面的教程,它解释了通过其他示例传递其他差异,如diff与方法Vs函数的其他示例,使用函数作为变量,创建返回函数的函数

方法和函数之间一个很大的实际区别是返回的含义。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

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第二版编程。 马丁·奥德斯基,莱克斯·斯彭,比尔·凡纳斯