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

时间:2015-04-30 11:35:27

标签: 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)
  })

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

onMouseClicked = { me => doSomething() }

me的推断类型为MouseEventT的类型范围是较低的类型范围,因此T必须是MouseEvent类型或MouseEvent的超类型,那么为什么me具有MouseEvent推断的Event类型?它不应该推断出最普​​遍的类型吗?

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

编辑:

假设我们进一步将T的类型限制为Event的子类型,其中MouseEventdef onMouseClicked_=[T >: MouseEvent <: Event](lambda: T => Unit) = setOnMouseClicked(new EventHandler[T] { override def handle(event: T): Unit = lambda(event) }) 的超类型。所以我们得到:

onMouseClicked = { me: MouseDragEvent => doSomething() }

所以如果我们这样做

MouseDragEvent

其中MouseEventme的子类型,编译因类型错误而失败,正如预期的那样,因为绑定确保MouseEvent必须是onMouseClicked = { me: Any => doSomething() } 的超类型

然而,如果我们这样做

Any

编译成功。很明显Event不是T的子类型,为什么编译成功呢?什么是{{1}}的推断类型?

1 个答案:

答案 0 :(得分:1)

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

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

trait Function1[-T1, +R]

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