2015-04-03 17 views
7

Nel REPL, sto scrivendo gli esempi da Reflection - TypeTags and Manifests.WeakTypeTag v. TypeTag

Sono confuso dalla differenza tra WeakTypeTag e TypeTag.

scala> import scala.reflect.runtime.universe._ 
import scala.reflect.runtime.universe._ 

typetag

scala> def paramInfo[T](x: T)(implicit tag: TypeTag[T]): Unit = { 
    | val targs = tag.tpe match { case TypeRef(_, _, args) => args } 
    | println(s"type tag of $x has type arguments $targs") 
    | } 
paramInfo: [T](x: T)(implicit tag: reflect.runtime.universe.TypeTag[T])Unit 

WeakTypeTag

scala> def weakParamInfo[T](x: T)(implicit tag: WeakTypeTag[T]): Unit = { 
    | val targs = tag.tpe match { case TypeRef(_, _, args) => args } 
    | println(s"type tag of $x has type arguments $targs") 
    | } 
weakParamInfo: [T](x: T)(implicit tag: reflect.runtime.universe.WeakTypeTag[T])Unit 

Esecuzione di un semplice, non esaustivo Esempio

scala> paramInfo2(List(1,2,3)) 
type of List(1, 2, 3) has type arguments List(Int) 

scala> weakParamInfo(List(1,2,3) 
    |) 
type tag of List(1, 2, 3) has type arguments List(Int) 

Qual è la differenza tra loro?

+3

Questa risposta è http://stackoverflow.com/questions/12218641/scala-what-is-a-typetag-and-how-do-i-use-it ma non con il miglior esempio – sschaef

risposta

9

TypeTag garantisce di avere un tipo concreto (ovvero uno che non contiene parametri di tipo o membri di tipo astratto); WeakTypeTag no.

scala> import scala.reflect.runtime.universe._ 
import scala.reflect.runtime.universe._ 

scala> def foo[T] = typeTag[T] 
<console>:10: error: No TypeTag available for T 
     def foo[T] = typeTag[T] 
         ^

scala> def foo[T] = weakTypeTag[T] 
foo: [T]=> reflect.runtime.universe.WeakTypeTag[T] 

Ma, naturalmente, non può effettivamente ottenere i parametri generici il metodo viene chiamato con se usato in questo modo:

scala> foo[Int] 
res0: reflect.runtime.universe.WeakTypeTag[Int] = WeakTypeTag[T] 

Si può costruire solo un TypeTag di un tipo generico se avete TypeTag s per tutti i parametri:

scala> def foo[T: TypeTag] = typeTag[List[T]] 
foo: [T](implicit evidence$1: reflect.runtime.universe.TypeTag[T])reflect.runtime.universe.TypeTag[List[T]] 

Se si dispone di un WeakTypeTag di tipo concreto, dovrebbe comportarsi la stessa di un TypeTag (per quanto ne so).