我有一个返回Future[Unit]
的方法,所以当我拨打whenReady
这两个选项有效:whenReady(doItAsync())(_ => {})
和whenReady(doItAsync()) { _ => }
但这并不是:whenReady(doItAsync())(() => {})
在这种情况下,_
类型Unit
和空参数列表是否等同?
答案 0 :(得分:2)
虽然类型Unit
类似于其他语言的void
,但它并不完全相同。
这个特殊问题来自Java(以及Scala)泛型实现的限制:它们是使用type erasure实现的。特别是它意味着泛型方法不能改变参数的数量。现在当类型参数为Unit
时会发生什么?我们仍然必须具有相同数量的参数,并且也不能神奇地改变返回类型以返回任何内容(void
),因为这将是一个不同的签名。所以答案是使用一些只有伪造值的假类型:scala.runtime.BoxedUnit
。因此Unit
可能代表您不需要但必须存在的实际参数。因此类型签名() => {}
与此不匹配,因为它不带参数。
另请注意,在Java本身存在同样的问题,因此有类似的事情称为java.lang.Void
<强>更新强>:
为了更清楚地说明如何遵循通用代码与非通用代码:
def foo(f: () => String) = println(f())
def fooGeneric[T](arg: T, f: (T) => String) = println(f(arg))
foo(() => "Non-generic")
fooGeneric[Unit]((), (_) => "generic")
请注意,逻辑上fooGeneric[Unit]
与foo
相同,您仍然必须传递第一个参数并传递接受(无用)参数的函数作为第二个参数。
答案 1 :(得分:2)
在这种情况下,不是_类型单位和空参数列表等同吗?
没有。 _ => {}
使用单个参数定义一个函数(在此上下文中发生类型Unit
),() => {}
定义一个没有参数的函数。他们的类型是Unit => Unit
和() => Unit
,或没有句法糖Function1[Unit, Unit]
和Function0[Unit]
。这些类型实际上并不相关:它们都不是另一个的子类型。
您可以使用模式匹配Unit
编写使用()
{ case () => ... }
的单参数匿名函数。pentaho-server-ce-7.1.0.0-12
。但没有必要这样做。