为什么_(下划线)类型单位和()对处理方式有所不同



我有一个返回 Future[Unit]的方法,所以当我调用 whenReady

这两个选项有效:whenReady(doItAsync())(_ => {})whenReady(doItAsync()) { _ => }

但这不是: whenReady(doItAsync())(() => {})

不是类型Unit_,在这种情况下是等价的空参数列表?

尽管类型Unit类型类似于其他语言的void,但它并不完全相同。此特定的麻烦来自Java(以及Scala)仿制药的限制:它们是使用类型擦除实现的。特别是这意味着通用方法无法更改参数的数量。现在,当类型参数为 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相同,您仍然必须传递第一个参数和传递函数,该函数接受(无用)参数为第二个参数。

在这种情况下,不是_的类型单位和空参数列表吗?

否。_ => {}定义了具有单个参数的函数(在此上下文中发生的Unit类型),() => {}定义一个没有参数的函数。它们的类型是Unit => Unit() => Unit,或没有句法糖Function1[Unit, Unit]Function0[Unit]。这些类型实际上并不相关:它们都不是另一种的亚型。

您可以使用模式匹配:{ case () => ... }编写单词匿名函数,将Unit()一起使用。但是没有意义。

最新更新