当使用抽象类型成员时,我不能在不使用asInstanceOf的情况下使用外部类型,还有其他选择吗?为什么抽象类型不能“覆盖”它,因此它知道它是一个Int或一个字符串?
scala> trait Param { type A
| val x:A
| def get:A = x
| }
scala> case class IParam(override val x:Int) extends Param {type A = Int}
defined class IParam
scala> case class SParam(override val x:String) extends Param {type A = String}
defined class SParam
scala> val s = Set[Param](IParam(1), SParam("s"))
s: scala.collection.immutable.Set[Param] = Set(IParam(1), SParam(s))
scala> val y:Int = s.head.get
<console>:26: error: type mismatch;
found : Param#A
required: Int
val y:Int = s.head.get
答案 0 :(得分:1)
编译器不会在类型检查s
时查看y
的定义,仅在其类型上。因此,它只知道s.head
是Param
,其A
是抽象的。为了让编译器告知s.head.get
是Int
,它必须知道s.head
是IParam
。
或者您可以这样看:如果选中此类型,则可以在不更改任何类型的情况下将s
的定义更改为val s = Set[Param](SParam("s"))
。但很明显,y: Int
不应该进行类型检查。
答案 1 :(得分:0)
使用类型别名的全部意义是封装来自外部世界的具体类型。这为您提供了实现类型的抽象。因此,如果您想将IParam
的类型更改为Double
,则无需在整个代码库中更改类型。
您可以在get
的函数签名中看到它返回的类型为A
而不是Int
def get : A = x
我认为您希望的功能可以通过以下方式实现:
scala> trait Param[T] { val x : T; def get : T = x }
defined trait Param
scala> val s = IParam(1)
s: IParam = IParam(1)
scala> val y : Int = s.get
y: Int = 1