我有一个从 JValue
中提取 Int
的代码,对于多个 JValue
子类来说应该看起来完全相同,所以我试图避免重复我自己。然而,事实上(见下文),scala 认为 j
是一个通用的 JValue
,并且 j.values
返回类型的值Values
,当然,它没有 isValidInt
和 toInt
方法。
jvalue \ name match {
case j @ (JInt | JDecimal | JDouble) => {
val num = j.values
if (num.isValidInt) num.toInt.success else reportError(name + " is not a valid int")
}
问题是避免重复的正确方法是什么?我不太热衷于将 JValue
转换为字符串,因为此代码适用于刚刚从字符串解析为 AST 的 json。我开始考虑为我需要的三种类型编写包装器,从这些类型到包装器的匹配和隐式转换器,然后为这些包装器创建一个父类(super class)以用作模式,但我不确定如何实现它。 p>
最佳答案
实现一个提取器以从任意 json 值中获取 Int
值,然后在您的问题匹配中使用该提取器。
object JsonInt {
def unapply(json: JValue): Option[Int] = json match {
case JInt(i) if i.isValidInt => Some(i.toInt)
case JDecimal(d) if d.isValidInt => Some(d.toInt)
case JDouble(d) if d.isValidInt => Some(d.toInt)
case _ => None
}
}
jvalue \ name match {
case JsonInt(num) => num.success
case _ => reportError(s"$name is not a valid int")
}
关于json - Scala 模式匹配多种类型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20054194/