Scala的类型推断如何与类型边界一起使用?

Ben*_*Lee 6 scala type-inference type-bounds

当类型参数存在类型边界时,Scala如何确定要推断的类型?例如:

def onMouseClicked_=[T >: MouseEvent](lambda: T => Unit) = 
  setOnMouseClicked(new EventHandler[T] {
    override def handle(event: T): Unit = lambda(event)
  })
Run Code Online (Sandbox Code Playgroud)

尝试使用此功能时,例如:

onMouseClicked = { me => doSomething() }
Run Code Online (Sandbox Code Playgroud)

me将具有推断类型MouseEvent.类型边界T是一个较低的类型边界,因此T必须是类型MouseEvent或超类型MouseEvent,所以为什么me有推断类型MouseEvent?它不应该推断出最普​​遍的类型吗?

是不是我不了解Scala的类型推断是如何工作的?或者我对类型界限的理解是完全错误的?

编辑:

假设我们进一步将T的类型限制为子类型Event,其中Event是超类型MouseEvent.所以我们得到:

def onMouseClicked_=[T >: MouseEvent <: Event](lambda: T => Unit) = 
  setOnMouseClicked(new EventHandler[T] {
    override def handle(event: T): Unit = lambda(event)
  })
Run Code Online (Sandbox Code Playgroud)

所以如果我们这样做

onMouseClicked = { me: MouseDragEvent => doSomething() }
Run Code Online (Sandbox Code Playgroud)

其中MouseDragEvent是子类型MouseEvent,编译因类型错误而失败,如预期的那样,因为绑定确保me必须是超类型MouseEvent.

然而,如果我们这样做

onMouseClicked = { me: Any => doSomething() }
Run Code Online (Sandbox Code Playgroud)

编译成功.很明显,Any它不是一个子类型Event,为什么编译成功呢?什么是推断类型T

Chr*_*tin 1

我对这个答案的准确性并不完全有信心,但这里是......

的类型lambaT => Unit,它是 的糖Function1[T, Unit],定义为:

trait Function1[-T1, +R]
Run Code Online (Sandbox Code Playgroud)

T用于第一个参数T1,它是逆变的,由-in指示-T1。对于逆变参数,层次结构中最低的类型是最通用的。