Json Scala模式匹配多种类型

Json Scala模式匹配多种类型,json,scala,pattern-matching,Json,Scala,Pattern Matching,我有一个从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.isV

我有一个从
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。我开始考虑为我需要的三种类型编写包装,将匹配和隐式转换器从这些类型转换为包装,然后为这些包装制作一个超类作为模式使用,但我不确定如何实现


是的,我意识到这里有多个类似的问题(比如和),但每个问题最多只包含解决方案的一部分

Scala对结构类型的支持有限。似乎
JValue
是这三种类型中最低的共同祖先。如果需要,您可以通过定义从
JValue
到某个包装类的隐式转换来绕过它,该包装类将具有
isValidInt
方法。

实现一个提取器,从任意json值中获取
Int
值,然后在mattern匹配中使用提取器

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")
}

如果您不想麻烦使用结构化键入,您可以使用
asInstanceOf
方法来使用
toInt
isValidInt
方法:

type IntExt = {

  def toInt: Int

  def isValidInt: Boolean

}
jvalue \ name match {

  case j @ (_: JInt | _: JDecimal | _: JDouble) =>
       
    val num = j.values.asInstanceOf[IntExt]

    if (num.isValidInt) num.toInt.success else reportError(name + " is not a valid int")
}

乍一看,这似乎是一个干净的解决方案,但实际上它看起来更像是
case JInt(i)=>如果(i.isValidInt)一些(i.toInt)其他的没有//JInt的i是一个BigInt
和JDecimal和JDouble的相同代码,这正是我试图避免的。我已经更新了我的答案,包括
isValidInt
检查,这比你说的要简单。另一个问题:您使用的是什么Json库?
`语法对于
lift json
来说很熟悉,它有一个
extractOpt[T]`方法,可以用来直接从任何JValue中提取一个
选项[Int]
。它可以将任何数值转换为
Int
extract[Int]
),唯一的问题是它不关心截断,例如2.1转换为2时没有错误。如果我必须编写自己的格式来关心截断,它将涉及与我们这里相同的详细程度。