I am trying to cast a String
to Int
using extractors. My code looks as follows.
object Apply {
def unapply(s: String): Option[Int] = try {
Some(s.toInt)
} catch {
case _: java.lang.Exception => None
}
}
object App {
def toT[T](s: AnyRef): Option[T] = s match {
case v: T => Some(v)
case _ => None
}
def foo(param: String): Int = {
//reads a Map[String,String] m at runtime
toT[Int](m("offset")).getOrElse(0)
}
}
I get a runtime error: java.lang.String cannot be cast to java.lang.Integer
. It seems the extractor is not being used at all. What should I do?
Edit: My use case is as follows. I am using play and I want to parse the query string passed in the url. I want to take the query string value (String) and use it as an Int, Double etc. For example,
val offset = getQueryStringAs[Int]("offset").getOrElse(0)
I think the biggest problem here is, that you seem to confuse casting and conversion. You have a Map[String, String]
and therefore you can't cast the values to Int
. You have to convert them. Luckily Scala adds the toInt
method to strings through implicit conversion to StringOps.
This should work for you:
m("offset").toInt
Note that toInt
will throw a java.lang.NumberFormatException
if the string can not be converted to an integer.
edit:
What you want will afaik only work with typeclasses.
Here is an example:
trait StringConverter[A] {
def convert(x: String): A
}
implicit object StringToInt extends StringConverter[Int] {
def convert(x: String): Int = x.toInt
}
implicit object StringToDouble extends StringConverter[Double] {
def convert(x: String): Double = x.toDouble
}
implicit def string2StringConversion(x: String) = new {
def toT[A](implicit ev: StringConverter[A]) = ev.convert(x)
}
usage:
scala> "0.".toT[Double]
res6: Double = 0.0