Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Map from Class[T] to T without casting

Tags:

scala

I want to map from class tokens to instances along the lines of the following code:

trait Instances {
  def put[T](key: Class[T], value: T)
  def get[T](key: Class[T]): T
}

Can this be done without having to resolve to casts in the get method?

Update:

How could this be done for the more general case with some Foo[T] instead of Class[T]?

like image 247
michid Avatar asked Sep 13 '11 11:09

michid


2 Answers

You can try retrieving the object from your map as an Any, then using your Class[T] to “cast reflectively”:

trait Instances {                                        
  private val map = collection.mutable.Map[Class[_], Any]()
  def put[T](key: Class[T], value: T) { map += (key -> value) }
  def get[T](key: Class[T]): T = key.cast(map(key))        
}
like image 102
Jean-Philippe Pellet Avatar answered Nov 11 '22 07:11

Jean-Philippe Pellet


With help of a friend of mine, we defined the map with keys as Manifest instead of Class which gives a better api when calling.

I didnt get your updated question about "general case with some Foo[T] instead of Class[T]". But this should work for the cases you specified.

object Instances {                                        
  private val map = collection.mutable.Map[Manifest[_], Any]()
  def put[T: Manifest](value: T) = map += manifest[T] -> value
  def get[T: Manifest]: T = map(manifest[T]).asInstanceOf[T]

  def main (args: Array[String] ) {
    put(1)
    put("2")
    println(get[Int])
    println(get[String])
  }
}
like image 38
Udayakumar Rayala Avatar answered Nov 11 '22 06:11

Udayakumar Rayala