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?
我对这个答案的准确性并不完全有信心,但这里是......
的类型lamba是T => Unit,它是 的糖Function1[T, Unit],定义为:
trait Function1[-T1, +R]
Run Code Online (Sandbox Code Playgroud)
T用于第一个参数T1,它是逆变的,由-in指示-T1。对于逆变参数,层次结构中最低的类型是最通用的。
| 归档时间: |
|
| 查看次数: |
857 次 |
| 最近记录: |