Scala中的val和def

时间:2018-04-21 05:09:01

标签: scala function

在我们喜欢的Scala中:

val fIncr: (x: int) => x+1

我的理解是,我们在这里定义一个函数文字。 Scala编译器会将其编译为扩展特征Function1的类,并在运行时将其实例化,并将函数值分配给fIncr。

如果我将类似的函数定义为方法会发生什么:

def mIncr(x: Int) = x+1

这是否编译成一个类?

编辑:

scala> val double = (i: Int) => {
 |     println("I am here")
 |     i * 2
 |   }
 double: Int => Int = $$Lambda$1090/773348080@6ae9b2f0

 scala> double(4)
 I am here
 res22: Int = 8

 scala> val evenFunc: (Int => Boolean) = {
 |                   println("I am here");
 |                    (x => x % 2 == 0)
 |              }
 I am here
 evenFunc: Int => Boolean = $$Lambda$1091/373581540@a7c489a

 scala> double
 res23: Int => Int = $$Lambda$1090/773348080@6ae9b2f0

 scala> evenFunc
 res24: Int => Boolean = $$Lambda$1091/373581540@a7c489a

 scala> evenFunc(10)
 res25: Boolean = true

 scala> def incr(x:Int) = x+1
 incr: (x: Int)Int

 scala> incr
 <console>:13: error: missing argument list for method incr
 Unapplied methods are only converted to functions when a function type is 
 expected.
 You can make this conversion explicit by writing `incr _` or `incr(_)` 
  instead of `incr`.
   incr
   ^

double和evenFunc是函数变量,我们已经为它们分配了函数文字。但是当输出显示时,当我们调用double时,也会执行println语句。但是,当定义时,evenFunc不执行println语句。 incr使用关键字def定义,因此其行为符合预期。

1 个答案:

答案 0 :(得分:2)

使用def时,

def mIncr(x: Int) = x+1

这是Scala中的方法。方法没有自己的身份。它总是属于一个类。但是当你使用val时,

val mIncr = (x: Int) => x + 1

这是Scala中的一个功能。函数是Scala中的完整对象。它有自己的身份。函数是Scala中的值。但方法不是价值观。

例如,如果您写入值,它将为您提供信息。

scala> def mIncr(x: Int) = x + 1
mIncr: (x: Int)Int

scala> val x = 4
x: Int = 4

scala> x
res0: Int = 4

scala> val inc = (x: Int) => x + 1
inc: Int => Int = <function1>

scala> inc
res1: Int => Int = <function1>

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

注意,当我编写mIncr时,编译器会抛出错误,因为它不是值。 用于扩展FunctionN特征的函数值适用于Scala版本2.12,但是在版本2.12发布之后。他们不创建匿名类。了解它here 函数可以像函数的参数一样传递。你不能用方法。当您传递方法时,Scala编译器会进行eta扩展。 Eta扩展意味着它将您的方法转换为函数值。