简单的Scala Mind Bender与闭包/高阶函数/方法

jhe*_*dus 2 scala

当我注意到下面的代码没有编译时,我正在玩Scala,为什么?

case class A(a:Int) {
   def getA: ()=>Int = () => a
   def getAA()=a
   def getAAA=a
}

object Test extends App{
  val a =A(3)
  def printInt(f:()=>Int)=println(f())
  printInt(a.getA)    // fine, prints 3
  printInt(a.getAA)   // fine, prints 3
  printInt(a.getAAA)  // this does not compile, why ?
}
Run Code Online (Sandbox Code Playgroud)

a.getA,a.getAA和a.getAAA有什么区别?

Deb*_*ski 7

当您定义def没有括号时,您可以定义它val.这意味着,必须在没有括号的情况下调用它(否则它们将是可选的).a.getAAA有类型Int.

当您定义def带(空)括号时,除非在函数也有效的上下文中使用括号,否则在调用者端使用括号是可选的.然后将没有括号的变体作为函数.

简而言之,以下类型是可能的:

scala> a.getAAA : Int
res: Int = 3

scala> a.getAA() : Int
res: Int = 3

scala> a.getAA : Int
res: Int = 3

scala> a.getAA : (() => Int)
res: () => Int = <function0>
Run Code Online (Sandbox Code Playgroud)

不可能的是:

scala> a.getAAA() : Int
<console>: error: Int does not take parameters
   a.getAAA() : Int
           ^

scala> a.getAAA : (() => Int)
<console>:11: error: type mismatch;
 found   : Int
 required: () => Int

scala> a.getAA() : (() => Int)
<console>: error: type mismatch;
 found   : Int
 required: () => Int
Run Code Online (Sandbox Code Playgroud)

如果要getAAA在函数上下文中使用,可以将其作为ad-hoc函数printInt(a.getAAA _).