相当混淆这个代码片段返回类型与&没有=

时间:2013-08-21 21:53:00

标签: scala closures equals-operator

object A extends App {

def closure1(x:Int) = {
  object O {
   def getX = x
   def add(y:Int) = x+y
  }
  val foo = O
  foo
}

def closure2(x:Int) {
  object O {
   def getX = x
   def add(y:Int) = x+y
  }
  val foo = O
  foo
}

println(closure1(4).getClass)
println(closure2(4).getClass)
}

result:
 $scala A
 class A$O$3$
 void
  1. 为什么返回类型不同?
  2. 我真的不关心返回类型。我想调用getX并添加 - 我想做一些像closes1(4).getX这样的事情 - 这是非法的。我该怎么做?

2 个答案:

答案 0 :(得分:15)

Scala对代码没有返回任何有趣值的简写表示法:省略=符号。在Java中,这将返回void,即根本没有;但在Scala中,它实际上是(),是Unit类型中唯一的成员。无论哪种方式,它都是相同的:没有任何东西或无意义的占位符。

你想要一个毫无意义的占位符的原因是,当你编写通用代码时,你宁愿不必处理某些事情的情况,而不是以不同的方式处理。

反正:

def f(): Unit = println("Hi")

是一个显式只返回无内容()值的函数(也是println返回的值)。简写就是

def f() { println("Hi") }

现在有一个偷偷摸摸的补充,就是在Scala中,与许多C派生语言一样,你可以放弃你所做的任何返回值。当你扔掉它时,剩下的就是()。 Scala会在closure2警告你你正在做一些可疑的事情:

<console>:16: warning: a pure expression does nothing in statement position
you may be omitting necessary parentheses
         foo
         ^
defined module A

但仍然允许你这样做(因为历史上预计这将有效)。

所以,总结一下:

def f {}

是一种仅返回无内容占位符()的方法。如果你完整地写出来,语法就是

def f: Unit = {}

当您尝试返回错误类型的值时,而不是抱怨它会抛弃该值并为您键入Unit,但通常会发出警告:

def f: Unit = 5
def f { 5 }

(请注意,意见主要是针对这些日子的短期形式(这些日子是2.10稳定),很大程度上是因为由于缺乏对差异的明确解释,新用户经常忽略=没有意识到它,然后想知道为什么事情不起作用。所以将来(2.11或2.12的弃用?)def f {}形式可能不起作用。)

如果你真的想要一个返回值 - 例如,你想要返回你的对象O(你可以直接做到这一点而不先将它分配给foo,顺便说一下),确保包含=

def f = { object O { def g = 5 }; O }

scala> f.g
res0: Int = 5

(提示:编译器会抱怨你在这里使用结构类型。你最好使用trait HasG { def g: Int }然后使用object O extends HasG;否则Scala实际上使用反射来调用{{1对于我从未完全遵循的一些基本原理。)

答案 1 :(得分:1)

我认为Rex解释了原因,你在定义=时省略了closure2,这使得Scala编译器认为你不想返回任何内容,即使你打算返回{{1} }。

foo

请注意scala> def closure3(x: Int) { | object O { | def getX = x | def add(y: Int) = x + y | } | val foo = O | foo | } <console>:17: warning: a pure expression does nothing in statement position; you may be omitting necessary parentheses foo ^ closure3: (x: Int)Unit 的返回类型为closure3

Unit

scala> def closure4(x: Int) = { | object O { | def getX = x | def add(y: Int) = x + y | } | O | } closure4: (x: Int)Object{def getX: Int; def add(y: Int): Int} scala> closure3(2) 不返回任何内容,因此您无法拨打closure3(2)

getX