2010-06-29 6 views
3

J'ai encapsulé un message et j'aimerais enregistrer le message que j'ai enveloppé.Comment obtenir la classe de _: Any

val any :Any = msg.wrappedMsg 
var result :Class[_] = null 

La seule solution que je pouvais trouver est tout assortit:

result = any match { 
    case x:AnyRef => x.getClass 
    case _:Double => classOf[Double] 
    case _:Float => classOf[Float] 
    case _:Long => classOf[Long] 
    case _:Int => classOf[Int] 
    case _:Short => classOf[Short] 
    case _:Byte => classOf[Byte] 
    case _:Unit => classOf[Unit] 
    case _:Boolean=> classOf[Boolean] 
    case _:Char => classOf[Char] 
} 

Je me demande s'il y a une meilleure solution? Les 2 approches suivantes ne fonctionnent pas :(

result = any.getClass //error 
// type mismatch; found : Any required: ?{val getClass: ?} 
// Note: Any is not implicitly converted to AnyRef. 
// You can safely pattern match x: AnyRef or cast x.asInstanceOf[AnyRef] to do so. 
result = any match { 
    case x:AnyRef => x.getClass 
    case x:AnyVal => /*voodoo to get class*/ null // error 
} 
//type AnyVal cannot be used in a type pattern or isInstanceOf 

Répondre

7

Vous pouvez appeler en toute sécurité .asInstanceOf[AnyRef] sur une valeur Scala, qui boîte primitives:

scala> val as = Seq("a", 1, 1.5,(), false) 
as: Seq[Any] = List(, 1, 1.5,(), false) 

scala> as map (_.asInstanceOf[AnyRef]) 
res4: Seq[AnyRef] = List(a, 1, 1.5,(), false) 

À partir de là, vous pouvez appeler getClass

.
scala> as map (_.asInstanceOf[AnyRef].getClass) 
res5: Seq[java.lang.Class[_]] = List(class java.lang.String, class java.lang.Int 
eger, class java.lang.Double, class scala.runtime.BoxedUnit, class java.lang.Boo 
lean) 

Testé avec 2.8.0.RC6, je ne sais pas cela a fonctionné en 2.7.7.

Certainement nouveau dans 2.8 sont les objets compagnons pour les classes dérivées de AnyVal. Ils contiennent box et unbox pratiques: méthodes

scala> Int.box(1) 
res6: java.lang.Integer = 1 

scala> Int.unbox(res6) 
res7: Int = 1 
3

Will not coulée ne vient le tour, comme suggéré dans le message d'erreur?


scala> val d:Double = 0.0 
d: Double = 0.0 

scala> d.asInstanceOf[AnyRef].getClass 
res0: java.lang.Class[_] = class java.lang.Double 
3

À partir du scala 2.10.0, getClass est disponible sur Any (et pas seulement sur AnyRef), de sorte que vous n'avez pas besoin de faire une contorsion plus et peut tout simplement faire any.getClass. Notez cependant que vous devez toujours être prêt à gérer la relation duale entre les types primitifs et leur version encadrée. Par exemple getClass sur une valeur entière sera de retour soit java.lang.Integer.TYPE (la classe du type Int primitive) ou classOf[java.lang.Integer] en fonction du type statique de la valeur:

scala> 123.getClass 
res1: Class[Int] = int 

scala> val x : Int = 123 
x: Int = 123 

scala> x.getClass 
res2: Class[Int] = int 

scala> val x: AnyVal = 123 
x: AnyVal = 123 

scala> x.getClass 
res3: Class[_] = class java.lang.Integer 

scala> val x: Any = 123 
x: Any = 123 

scala> x.getClass 
res4: Class[_] = class java.lang.Integer 
Questions connexes