从外部

时间:2016-02-21 19:10:27

标签: scala

当使用抽象类型成员时,我不能在不使用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

2 个答案:

答案 0 :(得分:1)

编译器不会在类型检查s时查看y的定义,仅在其类型上。因此,它只知道s.headParam,其A是抽象的。为了让编译器告知s.head.getInt,它必须知道s.headIParam

或者您可以这样看:如果选中此类型,则可以在不更改任何类型的情况下将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