Je veux obtenir le type d’une variable à l’exécution

Je veux obtenir le type d’une variable à l’exécution. Comment puis-je faire cela?

Ainsi, à proprement parler, le “type d’une variable” est toujours présent et peut être transmis en tant que paramètre de type. Par exemple:

val x = 5 def f[T](v: T) = v f(x) // T is Int, the type of x 

Mais selon ce que vous voulez faire , cela ne vous aidera pas. Par exemple, peut vouloir ne pas savoir quel est le type de la variable, mais savoir si le type de la valeur est un type spécifique, tel que ceci:

 val x: Any = 5 def f[T](v: T) = v match { case _: Int => "Int" case _: Ssortingng => "Ssortingng" case _ => "Unknown" } f(x) 

Ici, peu importe le type de la variable, Any . Ce qui compte, ce qui est vérifié, c’est le type de 5 , la valeur. En fait, T est inutile – vous auriez aussi bien pu l’écrire à la place def f(v: Any) . En outre, cela utilise soit ClassTag ou une Class de valeur, qui sont expliquées ci-dessous, et ne peut pas vérifier les parameters de type d’un type: vous pouvez vérifier si quelque chose est une List[_] ( List de quelque chose), mais pas Par exemple, une List[Int] ou une List[Ssortingng] .

Une autre possibilité est que vous souhaitiez réifier le type de la variable. C’est-à-dire que vous voulez convertir le type en une valeur, de manière à pouvoir la stocker, la transmettre, etc. Cela implique une reflection et vous utiliserez ClassTag ou TypeTag . Par exemple:

 val x: Any = 5 import scala.reflect.ClassTag def f[T](v: T)(implicit ev: ClassTag[T]) = ev.toSsortingng f(x) // returns the ssortingng "Any" 

Un ClassTag permettra également d’utiliser les parameters de type que vous avez reçus lors du match . Cela ne marchera pas:

 def f[A, B](a: A, b: B) = a match { case _: B => "A is a B" case _ => "A is not a B" } 

Mais cela va:

 val x = 'c' val y = 5 val z: Any = 5 import scala.reflect.ClassTag def f[A, B: ClassTag](a: A, b: B) = a match { case _: B => "A is a B" case _ => "A is not a B" } f(x, y) // A (Char) is not a B (Int) f(x, z) // A (Char) is a B (Any) 

J’utilise ici la syntaxe des limites de contexte , B : ClassTag , qui fonctionne exactement comme le paramètre implicite de l’exemple ClassTag précédent, mais utilise une variable anonyme.

On peut également obtenir un ClassTag partir d’une Class de valeur, comme ceci:

 val x: Any = 5 val y = 5 import scala.reflect.ClassTag def f(a: Any, b: Any) = { val B = ClassTag(b.getClass) ClassTag(a.getClass) match { case B => "a is the same class as b" case _ => "a is not the same class as b" } } f(x, y) == f(y, x) // true, a is the same class as b 

Un ClassTag est limité car il ne couvre que la classe de base, mais pas ses parameters de type. En d’autres ClassTag , le ClassTag pour List[Int] et List[Ssortingng] est le même, List . Si vous avez besoin de parameters de type, vous devez utiliser un TypeTag place. Un TypeTag cependant, ne peut pas être obtenu à partir d’une valeur, et ne peut pas non plus être utilisé pour une correspondance de modèle, en raison de l’ effacement de la JVM.

Les exemples avec TypeTag peuvent devenir assez complexes – ne pas même comparer deux tags de type n’est pas tout à fait simple, comme on peut le voir ci-dessous:

 import scala.reflect.runtime.universe.TypeTag def f[A, B](a: A, b: B)(implicit evA: TypeTag[A], evB: TypeTag[B]) = evA == evB type X = Int val x: X = 5 val y = 5 f(x, y) // false, X is not the same type as Int 

Bien sûr, il existe des moyens de rendre cette comparaison vraie, mais cela nécessiterait quelques chapitres de livre pour vraiment couvrir TypeTag , alors je vais m’arrêter ici.

Enfin, peut-être que vous ne vous souciez pas du type de la variable. Peut-être que vous voulez juste savoir quelle est la classe d’une valeur, auquel cas la réponse est plutôt simple:

 val x = 5 x.getClass // int -- technically, an Int cannot be a class, but Scala fakes it 

Il serait cependant préférable d’être plus précis sur ce que vous voulez accomplir, afin que la réponse soit plus pertinente.

Je pense que la question est incomplète. si vous voulez dire que vous souhaitez obtenir les informations de type d’une classe de classe, puis ci-dessous:

Si vous souhaitez imprimer comme vous l’avez spécifié, alors:

 scala> def manOf[T: Manifest](t: T): Manifest[T] = manifest[T] manOf: [T](t: T)(implicit evidence$1: Manifest[T])Manifest[T] scala> val x = List(1,2,3) x: List[Int] = List(1, 2, 3) scala> println(manOf(x)) scala.collection.immutable.List[Int] 

Si vous êtes en mode repl, alors

 scala> :type List(1,2,3) List[Int] 

Ou si vous voulez juste savoir ce que le type de classe alors comme @monkjack explique "ssortingng".getClass pourrait résoudre le but

Si, par le type d’une variable, vous voulez dire la classe d’exécution de l’object sur lequel la variable pointe, vous pouvez l’obtenir via la référence de classe dont disposent tous les objects.

 val name = "sam"; name: java.lang.Ssortingng = sam name.getClass res0: java.lang.Class[_] = class java.lang.Ssortingng 

Si toutefois vous voulez dire le type que la variable a été déclarée, alors vous ne pouvez pas l’obtenir. Par exemple, si vous dites

 val name: Object = "sam" 

alors vous aurez toujours une Ssortingng retour du code ci-dessus.

j’ai testé ça et ça a fonctionné

 val x = 9 def printType[T](x:T) :Unit = {println(x.getClass.toSsortingng())}