为什么Scala在我的抽象类中以相同的方式推断类型参数?

时间:2015-12-02 19:56:28

标签: scala inheritance abstract-class type-inference traits

我已经定义了两个特征:ABB延伸A。我还定义了一个类型参数化函数addOne,它将A的任何子类型作为输入参数。我可以使用B实例作为输入调用此函数,因为B扩展A(请参阅success)。但是,当我尝试在抽象类的上下文中做同样的事情时,这不再起作用了。我错过了什么?

trait A {
  val a: Int
}

trait B extends A {
  val b: Int
}

def addOne[T <: A](t: T): Int = t.a + 1

def success[U <: B](u: U): Int = addOne(u)  // this works!


abstract class C[T <: A, U <: B] {

  def addTwo(t: T): Int = t.a + 2

  def fail(u: U): Int = addTwo(u)  // this doesn't compile

}

谢谢!

2 个答案:

答案 0 :(得分:3)

这是因为在C类中,当你知道U是B的子类型而T是A的子类型时,你并不能保证U是T的子类型。

编辑:我想我找到了办法。它使用generalised type constraints

abstract class C[T <: A, U <: B] {

  def addTwo(t: T): Int = t.a + 2

  def fail(u: U)(implicit ev: U <:< T): Int = addTwo(u)  // compiles

}
但是,我还没有对此进行过全面的测试。

答案 1 :(得分:0)

我不知道C在做什么,但我会说:

@IBAction func changeButtonPressed(sender: AnyObject) {
  self.navigationController.popViewControllerAnimated(true)
}

也就是说,你只是想说无论T和U是什么,你传给g的东西都是。

就像其他答案所说的那样,你施加约束的地方取决于你想要做什么。