下面的函数应该采用value
类型的String
并返回与该函数第二个参数的类型匹配的Option
,例如
toOption[Double]("10", classOf[Double])
def toOption[A](value: String, classType: A): Option[A] = {
classType match {
case _: Int => {
try {
Some(value.trim().toInt)
} catch {
case e: NumberFormatException => None
}
}
case _: Double => {
try {
Some(value.trim().toDouble)
} catch {
case e: NumberFormatException => None
}
}
case _: java.sql.Timestamp => {
try {
Some(java.sql.Timestamp.valueOf(value.trim()))
} catch {
case e: NumberFormatException => None
}
}
case _ => None
}
}
但是,就目前的功能而言,我收到以下错误。我如何/应该如何解决这些错误?
<console>:15: error: type mismatch;
found : Int
required: A
Some(value.trim().toInt)
^
<console>:22: error: type mismatch;
found : Double
required: A
Some(value.trim().toDouble)
^
<console>:29: error: type mismatch;
found : java.sql.Timestamp
required: A
Some(java.sql.Timestamp.valueOf(value.trim()))
答案 0 :(得分:4)
是的,您必须强制转换:Some(value.trim.toInt).asInstanceOf[A]
。它不知道A为Int
。
这是一个更好的方法:
trait FromString[T] {
def convert(s: String): T
def apply(s: String): Option[T] = Try(convert(s.trim)).toOption
}
implicit object IntFromString extends FromString[Int] {
def convert(s: String) = s.toInt
}
implicit object DoubleFromString extends FromString[Double] {
def convert(s: String) = s.toDouble
}
// etc.
所以,现在,您可以编写:
def toOption[T : FromString](s: String): Option[T] = implicitly[FromString[T]](s)
或者,如果您想在未定义转化的情况下找回None
:
def toOption[T](s: String)(implicit conv: FromString[T] = null) = Option(conv)
.flatMap(_.apply(s))
答案 1 :(得分:0)
铸造解决了您的问题,因为编译器无法将映射与您从模式匹配中获得的类型相关联。
import scala.util.Try
def toOption[A](value: String, classType: A): Option[A] = {
classType match {
case _: Int =>
Try {
value.trim().toInt.asInstanceOf[A]
} toOption
case _: Double =>
Try {
value.trim().toDouble.asInstanceOf[A]
} toOption
case _: java.sql.Timestamp =>
Try {
java.sql.Timestamp.valueOf(value.trim()).asInstanceOf[A]
} toOption
case _ => Option.empty[A]
}
}
编辑:@Dima使用类型类的解决方案更优雅