views:

164

answers:

2

I've wrapped a Message and would like to log which message I've wrapped.

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

The only solution I could find is matching everything:

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]
}

I wonder if there's a better solution? The following 2 approaches do not work :(

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
+3  A: 

Won't casting just do the trick, as suggested in the error message?


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

scala> d.asInstanceOf[AnyRef].getClass
res0: java.lang.Class[_] = class java.lang.Double
Arjan Blokzijl
+5  A: 

You can safely call .asInstanceOf[AnyRef] on any Scala value, which will box 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)

From there, you can call 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)

Tested with 2.8.0.RC6, I don't know it this worked in 2.7.7.

Definitely new in 2.8 are the companion objects for the classes derived from AnyVal. They contain handy box and unbox methods:

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

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