简体   繁体   中英

Access abstract type member from outside

When using an abstract type member I can't use the type from outside without using asInstanceOf, is there any other choice? Why doesn't the abstract type let itself be "overriden" so it know it's an Int or a String?

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

The compiler isn't going to be looking at the definition of s while type-checking y , only at its type. So it only knows that s.head is a Param , and its A is abstract. To let the compiler tell that s.head.get is Int , it must know s.head is IParam .

Or you can see it like this: if this type-checked, then you could change definition of s to val s = Set[Param](SParam("s")) without changing any types. But then it's clear that y: Int shouldn't type-check.

The whole point of using type aliases is to encapsulate the concrete type from the outside world. This gives you an abstraction of what the implementation type is. Therefore if you wanted to change the type of IParam to a Double , you wouldn't have to change the type throughout your entire code base.

You can see in the function signature of get that it returns a type A NOT an Int

def get : A = x

I think the functionality you desire could be achieved the following way:

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM