简体   繁体   中英

Understanding Tagged Types and asInstanceOf

I use tagged types from Miles Sabin gist:

type Tagged[U] = { type Tag = U }
type @@[T, U] = T with Tagged[U]

trait MyTrait

def tag(s: String): String @@ MyTrait = s.asInstanceOf[String @@ MyTrait]

Which I can use like this (and it works):

scala> tag("lala")
res7: @@[String,MyTrait] = lala

My question is: how? How doesn't this throw ClassCastexception : s.asInstanceOf[String @@ MyTrait] . From my point of view, "lala" is of type String but not of type String with { type Tag = MyTrait} since it was instantiated like usual String object. What is the magic with asInstanceOf method?

First, note that the whole point of tagged types is to avoid runtime overhead, but this also means you can't expect runtime type checks to work for distinguishing them!

asInstanceOf is a runtime cast, and JVM doesn't know the Scala type system (or even Java's); it only has classes, interfaces, and primitives. So asInstanceOf can only cast to the erased type, ie the closest JVM equivalent of the Scala type. Erased type of String with { type Tag = MyTrait} is String , so it succeeds.

The relevant parts of the specification are:

  1. Standard Library defines asInstanceOf as follows:

     /** Type cast; needs to be inlined to work as given */ def asInstanceOf[A]: A = this match { case x: A => x case _ => if (this eq null) this else throw new ClassCastException() } 
  2. Type patterns explains how x: String with { type Tag = MyTrait } is matched:

    Types which are not of one of the forms described above are also accepted as type patterns. However, such type patterns will be translated to their erasure. The Scala compiler will issue an "unchecked" warning for these patterns to flag the possible loss of type-safety.

  3. Finally ,

    The erasure of a compound type T1 with … with Tn {R} is the erasure of the intersection dominator of T1,…,Tn .

    In this case T1 is String , T2 is AnyRef { type Tag = MyTrait } , so you get the intersection dominator of String and AnyRef , which is String .

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