1

I'd like to put some data into a HashMap and retrieve these as typed values using a function. The function takes the expected type and also a default value in case the value is not stored in the HashMap. Type erasure of the JVM makes this a tricky thing.

Q: How can I retrieve a typed value?

Code and results below.

abstract class Parameters(val name: String) {
  val parameters = new HashMap[String, Any]()

  def put(key: String, value: Any) = parameters(key) = value

  def get(key: String) = parameters.getOrElse(key, None)

  def remove(key: String) = parameters.remove(key)


  def g0[T: TypeTag](key: String, defaultValue: T) = {
    get(key) match {
      case x: T => x
      case None => defaultValue
      case _ => defaultValue
    }
  }


  def g1[T: ClassTag](key: String, defaultValue: T) = {
    val compareClass = implicitly[ClassTag[T]].runtimeClass

    get(key) match {
      case None => defaultValue
      case x if compareClass.isInstance(x) => x.asInstanceOf[T]
    }
  }
}

class P extends Parameters("AParmList") {
  put("1", 1)
  put("3", "three")
  put("4", 4.0)
  put("width", 600)

  println(g0[Int]("width", -1))
  println(g0[Int]("fail", -2))
  println(g1[Int]("width", -3))
  println(g1[Int]("fail", -4))
}


object TypeMatching {
  def main(args: Array[String]) {
    new P
  }
}

The output is (comments in parenthesis): 600 (as expected) None (expected -2) and a match error (java.lang.Integer stored, Int required)

osx
  • 146
  • 1
  • 11
  • Related: http://stackoverflow.com/questions/16825927/classtag-based-pattern-matching-fails-for-primitives – 0__ Aug 03 '15 at 09:20
  • Would it be a problem for you to use `Class` objects ? It would make the syntax a bit more explicit in places where you cannot hide the use of `Class`, but I think this would make it easier – Dici Aug 03 '15 at 10:44

0 Answers0