【发布时间】:2019-09-30 11:19:41
【问题描述】:
我正在尝试定义一个具有类型边界的类。
trait External[T]{
def deserialize( bytes: Array[Byte] ) : T
}
trait A
case class Hi(i: Int) extends A
class Foo[X >: A] extends External[X] {
def deserialize(bytes: Array[Byte]) : X = Hi(1)
}
scala> new Foo[Hi]
但我收到以下错误:
<console>:14: error: type arguments [Hi] do not conform to class Foo's type parameter bounds [X >: A]
val res2 =
^
我做错了什么?我该如何解决? 编辑: 如果我尝试恢复绑定的 Foo[X <: a y>
scala> class Foo[X <: A]{
def deserialize(bytes: Array[Byte]): X = Hi(1)
}
<console>:13: error: type mismatch;
found : Hi
required: X
def deserialize(bytes: Array[Byte]): X =Hi(1)
^
我可以通过这样做来解决它:
class Foo[X <: A]{
def deserialize(bytes: Array[Byte]): X = a.asInstanceOf[X]
}
这是惯用的方式还是有更好的方式?
【问题讨论】:
-
您的类型范围不正确。如果您只想允许扩展
A的类型,那么您需要使用[X <: A, Y <: A] -
问题还不清楚。
a是什么,Y的类型是什么?您能否清理此问题以提供完整的示例来显示您尝试修复的错误。最好避免将 REPL 用于此类事情,因为它并不总是按您期望的方式工作。 -
@Tim
Y确实是多余的,是我现在清理的旧代码 -
@igx
a来自哪里? - 另外,从错误中说它是A类型,但你说你的返回类型是X,它应该是A的子类型,你不能(安全地)将A的任意实例转换为X。 -
@igx 同样,问题是你说你会返回一个
X(任何类型的X),但你返回的是一个Hi。你不能保证Hi <:< X。例如,假设另一个用户定义了case class Hey(s: String) extends A,然后它尝试使用Foo[Hey],而你返回一个Hi,一切都会崩溃。 - 我相信这可以使用 typeclasses 轻松解决,但问题尚不清楚。介意打开一个新问题来解释您的寄宿生问题吗?
标签: scala generics subtype subtyping