为什么不尝试[List [MyClass]]符合Try [List [T<:MyClass]]?

时间:2014-11-29 11:27:21

标签: scala types

我正在尝试使用以下签名定义方法:

def parse[T <: MyClass](statement: String): Try[List[T]] = {

我的班级是一个抽象班:

sealed abstract class MyClass { }

case class MyClassChild(v: Int) extends MyClass

我的parse方法返回Success(List [MyClassChild])

但编译器抱怨以下错误:

Error:(124, 19) type mismatch;
 found   : scala.util.Try[List[parser.MyClass]]
 required: scala.util.Try[List[T]]

为什么不scala.util.Try[List[parser.MyClass]]符合scala.util.Try[List[T]],因为T <: MyClass

谢谢

1 个答案:

答案 0 :(得分:1)

T应该是>: MyClassTry[List[T]] >: Try[List[MyClass]](列表并且还尝试covariant,因此它会起作用)以确认返回类型 - 因为您的函数无法返回比声明的更大的类型(见Liskov substitution principle):

scala> trait A { type MT; def aaa[T <: MT]: List[T] = null.asInstanceOf[List[MT]] }
<console>:7: error: type mismatch;
 found   : List[A.this.MT]
 required: List[T]


scala> trait A { type MT; def aaa[T >: MT]: List[T] = null.asInstanceOf[List[MT]] }
defined trait A

如果您想要T <: MyClass - 您应该将返回类型更改为Try[List[MyClass]]

scala> trait A { type MT; def aaa[T <: MT]: List[MT] = null.asInstanceOf[List[MT]] }
defined trait A

换句话说,即使理论上你也不能将MyClass“缩小”到T,因为T <: MyClass定义它更大。 MyClass.asInstanceOf[T]会以概率&gt;为您提供输入错误0,就像Any.asInstanceOf[String]