我正在尝试使用以下签名定义方法:
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
?
谢谢
答案 0 :(得分:1)
T
应该是>: MyClass
和Try[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]
。