3

Assume I have follwing code

def get[T](name:String)(implicit mf:ClassManifest[T]):T = mf.erasure match {
     case classOf[Boolean] => obj.getBoolean(name)
     case classOf[Int] => obj.getInt(name)
   }

Now code dosn't work because classOf[Int] is invalid match value.

yura
  • 14,489
  • 21
  • 77
  • 126
  • 1
    if you need only value types, take a look at ClassManifest, def fromClass[T](clazz: JClass[T]): ClassManifest[T] = clazz match { case java.lang.Byte.TYPE => Byte.asInstanceOf[ClassManifest[T]] .... – tuxSlayer Feb 28 '12 at 20:23

2 Answers2

5

You should almost certainly investigate alternatives to using manifests and matching on class objects. In this case type classes will provide a much cleaner solution,

// Assuming that Store is the type of obj ...

trait Get[T] { def get(s : Store, name : String) : T }
implicit val getBoolean = new Get[Boolean] {
  def get(s : Store, name : String) : Boolean = s.getBoolean(name)
}
implicit val getInt = new Get[Int] {
  def get(s : Store, name : String) : Int = s.getInt(name)
}

def get[T](name : String)(implicit inst : Get[T]) : T = inst.get(obj, name)

With this implementation, rather than getting a match error at runtime if you ask for an unsupported type, you will instead get a static compile time error.

Also note that being a compile time resolution mechanism, applied before erasure, this technique is a lot more precise than matching at runtime post-erasure. For instance, using this technique we can distinguish between the List[Int] and List[String] case, whereas they would be equated by a runtime test.

Miles Sabin
  • 23,015
  • 6
  • 61
  • 95
3

This works for me:

val mf = //some manifest
mf.erasure match {
  case c if c == classOf[String] => "string!"
  case c if c == classOf[Int] => "int!"
  case c if c == classOf[Boolean] => "bool!"
  //...
}
Dylan
  • 13,645
  • 3
  • 40
  • 67
  • A note: this method is just fine for trivial things, but Miles's answer highlights an important point: compile-time errors are much easier to detect than run-time errors. This way will give you a run-time error if you try it on a `classOf[SomethingElse]`, whereas using implicits will give you a compiler error if you try get[SomethingElse] if there's no implicit available. – Dylan Feb 29 '12 at 19:28