2017-09-20 2 views
0

Est-il possible de lancer un objet à l'aide de son Type. Par exemple:Diffuser un objet à l'aide de son Type

import scala.reflect.api.Types 

val t: Types#Type = ...// real type of the object o below 
println(t)   // out: com.project.Event[java.lang.String] 
val o: Any = ...  // some object which has above type 


val e: com.project.Event[java.lang.String] = cast(o, t) 

def cast(o: Any, t: Type) = ??? 

Répondre

0

Je pense que vous pouvez utiliser TypeTag pour maintenir l'information de type et de le jeter sur le type de cible, comme:

import scala.reflect.runtime.universe._ 

// get TypeTag by typeTag[A] 
val t: TypeTag[com.project.Event[java.lang.String]] = typeTag[com.project.Event[java.lang.String]] 

//cast with typeTag 
val r:com.project.Event[java.lang.String] = cast(o, t) 
def cast[A](o: Any, t: TypeTag[A]) = o.asInstanceOf[A] 

si vous ne pouvez pas obtenir directement TypeTag, peut-être vous voulez convertir le Type-TypeTag:

Get a TypeTag from a Type?

1

Si vous utilisez exactement Type (pas TypeTag[T]) - en général non, car l'instance de Type ne stocke aucune information dans la compilation: il n'y a pas de membres/paramètres de niveau de type qui stockent cette information. Donc, si vous utilisez Type en cours d'exécution - il n'y a aucun moyen de savoir à quel type de compilation il correspond (quel est le type de retour de votre fonction de distribution? _? :)).

Ainsi, votre casting devrait avoir une signature comme:

def cast[T](o: Any, t: Type): T = o.asInstanceOf[T] 

auquel cas Type ne contribue pas vraiment comme (contrairement TypeTag[T]), il ne prévoit rien pour l'inférence de type de T. Même conversion from Type to TypeTag[T] vous oblige évidemment à spécifier le type explicitement, comme cast[String] et ainsi de suite.

La seule chose Type peut être utilisé pour est de vérifier si o correspond effectivement t:

def cast[T](o: Any, t: Type): Option[T] = 
    if (mirror.reflect(o).symbol == t.typeSymbol) Some(o.asInstanceOf[T]) else None 

à quelque chose comme:

def cast[T: TypeTag](o: Any, t: Type): Option[T] = 
    if (mirror.reflect(o).symbol == t.typeSymbol && typeOf[T] =:= t) 
    Some(o.asInstanceOf[T]) 
    else None 

Une exception évidente est quand vous avez obtenu un Type à l'intérieur d'une macro, de sorte que vous pouvez composer un arbre avec asInstanceOf correcte dans la compilation:

https://groups.google.com/forum/#!topic/scala-user/3YF_98W9eSE