斯卡拉def模棱两可

时间:2013-08-01 20:13:35

标签: scala scala-2.10

刚刚拿起Scala。尽管有许多在线教程,但发现它非常难以掌握语言的基础知识。有人可以解释以下代码的细微差别吗? (使用scala 2.10.2)

案例1

scala> def greet = println("helloo")
greet: Unit
scala> greet
helloo
scala> greet()
<console>:9: error: Unit does not take parameters
          greet()
               ^

案例2

scala> def greet = ()=>println("helloo")
greet: () => Unit
scala> greet
res31: () => Unit = <function0>
scala> greet()
helloo

案例3

scala> def greet() = println("helloo")
greet: ()Unit
scala> greet
helloo
scala> greet()
helloo

然而令人惊讶的是,Scala语言没有明确的概念性描述 对不起,如果这是一个全新的问题!

1 个答案:

答案 0 :(得分:8)

Scala可以有任意数量的参数块,而不仅仅是一个。所以:

def f(i: Int) = i + 2
def g(i: Int)(j: Int) = i + j
def h(i: Int)(j: Int)(b: Boolean) = if (b) i + j else i * j

一切正常。参数块是一种组织参数并向编译器发出信号的方法,如何处理从方法(def)到函数的转换(这是一种可以作为参数传递的方法)。

现在,如果您有空参数块,可以省略它们以简化:

def a()()() = println("Hi") // Do nothing!
a()()()                     // Full call
a()                         // Drop some
a                           // Drop all of them

a的所有调用都做同样的事情。但是你不能添加比属于更多的空参数块 - 这些参数块被解释为对方法返回的任何内容的调用。

a()()()()                   // No go, calls `()` on `Unit` which doesn't exist

所以这涵盖了你的第1和第3个案例。

现在,您还可以使用方法返回一个函数。函数将参数(只有一个块!)映射到输出,但与方法不同,您可以传递它。 (Scala擅长在需要时自动将方法包装到函数中。)

所以

def b = () => println("Hi")

说每次调用b时,都应创建一个不带参数的函数,并返回println("Hi")返回的内容。实际上,它返回Unit,即没有返回值 - 它实际上是一个值,但它始终是相同的实体:()。这避免了必须为返回void的过程/方法和具有返回值的方法的特殊情况;一切都有回报值(至少在概念上)。无论如何,如果你有一个:

val c = b

然后你可以称之为:

c()    // Will print "Hi"

或者你可以一次创建和调用所有

b()    // The `b` part creates the function, `()` calls it.

游览例如Programming in Scala将涵盖您在这方面需要的所有基础知识。 (我喜欢有纸质副本,即使有人必须付钱。)