我对匿名函数定义感到困惑如下:
var plusOne = (x:Int)=>x+1
// or val plusOne=(x:Int)=>x+1
println(plusOne(2))
或者
def plusOne = (x:Int)=>x+1
println(plusOne(2))
对于函数名称,请var
/ val
和def
之间有什么区别。
答案 0 :(得分:5)
示例 -
var plusOneVar = (x:Int)=>x+1
val plusOneVal = (x:Int)=>x+1
def plusOneDef = (x:Int)=>x+1
plusOneVar = (x:Int)=>x+2 // Reassignment to var is valid
plusOneVal = (x:Int)=>x+2 // Compile time error, reassignment to val
plusOneDef = (x:Int)=>x+2 // Compile time error, reassignment to val
因为您正在查看具有函数的示例,所以很难理解。让我们尝试用简单的变量来理解它。
var symbolVar = 100 // line 1
val symbolVal = symbolVar // line 2
def symbolDef = symbolVar // line 3
println(symbolVar) // prints 100
println(symbolVal) // prints 100
println(symbolDef) // prints 100 - no surprise yet
symbolVar = symbolVar + 1
println(symbolVal) // still prints 100 which was evaluated and assigned on line 2
println(symbolDef) // prints 101 as symbolDef is a def and it depends on symbolVar, line 3 is evaluated again
答案 1 :(得分:2)
可以重新分配。
var plusOne
无法重新分配。两者都被评估一次。每次调用val plusOne
时都会对其进行评估
答案 2 :(得分:1)
还要注意val
(或var
)函数的一个实例被创建并用于该函数的任意数量的调用,而def
是一个新的实例。为每次调用创建函数。然而,对于
def f (i:Int) = i+1
f: (i: Int)Int
注意
val g = f _
g: Int => Int = <function1>
答案 3 :(得分:0)
使用javap
从类文件反汇编程序结果中可以清楚地看出。将以下代码保存为Test.scala
class Test {
val fVal: Int => Int = x => x + 1
var fVar: Int => Int = x => x + 1
def fDef(x: Int): Int = { x + 1 }
}
并且scalac Test.scala; javap Test
会显示
Compiled from "Test.scala"
public class Test {
public scala.Function1<java.lang.Object, java.lang.Object> fVal();
public scala.Function1<java.lang.Object, java.lang.Object> fVar();
public void fVar_$eq(scala.Function1<java.lang.Object, java.lang.Object>);
public int fDef(int);
public Test();
}
如上面的结果所示,val
和fVar
表示为返回Function1对象的方法。区别在于fVar
有一个额外的&#34; setter&#34;。虽然fDef
与普通的Java方法类似。