繁体   English   中英

提取具有上限的案例类

[英]Extracting a case class with an upper bound

我想从JSON字符串中提取案例类,并为每个类重用代码。 这样的问题将是完美的。 但这意味着我必须为要提取的每个类编写代码。

我希望做这样的事情:

abstract class SocialMonitorParser[C <: SocialMonitorData] extends Serializable {

  def toJSON(socialMonitorData: C): String = {
    Requirements.notNull(socialMonitorData, "This field cannot be NULL!")
    implicit val formats = DefaultFormats
    write(socialMonitorData)
  }

  def fromJSON(json: String): Option[C] = {
    implicit val formats = DefaultFormats // Brings in default date formats etc.
    val jsonObj = liftweb.json.parse(json)

    try {
      val socialData = jsonObj.extract[C]
      Some(socialData)
    } catch {
      case e: Exception => {
        Logger.get(this.getClass.getName).warn("Unable to parse the following JSON:\n" + json + "\nException:\n" + e.toString())
        None
      }
    }
  }

}

但这给了我以下错误:

Error:(43, 39) No Manifest available for C.
val socialData = jsonObj.extract[C]
Error:(43, 39) not enough arguments for method extract: (implicit formats: net.liftweb.json.Formats, implicit mf: scala.reflect.Manifest[C])C.
Unspecified value parameter mf.
val socialData = jsonObj.extract[C]

我希望我可以做这样的事情,也许有办法。 但是我无法解决这个问题。

我将尝试用其他一些信息来扩展这个问题。 假设我有Twitter和Facebook数据,以防此类情况:

case class FacebookData(raw_data: String, id: String, social: String) extends SocialMonitorData
case class TwitterData(...) extends SocialMonitorData{ ...}

我希望一旦通过Upper Bound类型,就可以重用fromJSONtoJSON

class TwitterParser extends SocialMonitorParser[TwitterData] {

覆盖FromJSON}类FacebookParser扩展了SocialMonitorParser [FacebookData]

多谢。

我不确定为什么要让SocialMonitorParserabstract或可Serializable或者您将如何使用它,但是如果您仔细观察该错误,您可能会看到编译器想要CManifest Manifest是Scala通过JVM强制对泛型强制执行的类型擦除来保留类型信息的一种方式。 如果您修复了该错误,则将编译如下代码:

import net.liftweb.json._
import net.liftweb.json.Serialization._

trait SocialMonitorData

case class FacebookData(raw_data: String, id: String, social: String) extends SocialMonitorData


class SocialMonitorParser[C <: SocialMonitorData : Manifest] extends Serializable {

  def toJSON(socialMonitorData: C): String = {
    // Requirements.notNull(socialMonitorData, "This field cannot be NULL!")
    implicit val formats = DefaultFormats
    write(socialMonitorData)
  }

  def fromJSON(json: String): Option[C] = {
    implicit val formats = DefaultFormats // Brings in default date formats etc.
    val jsonObj = parse(json)

    try {
      val socialData = jsonObj.extract[C]
      Some(socialData)
    } catch {
      case e: Exception => {
        // Logger.get(this.getClass.getName).warn("Unable to parse the following JSON:\n" + json + "\nException:\n" + e.toString())
        None
      }
    }
  }
}

您可以将其用作

def test(): Unit = {
  val parser = new SocialMonitorParser[FacebookData]

  val src = FacebookData("fb_raw_data", "fb_id", "fb_social")
  println(s"src = $src")

  val json = parser.toJSON(src)
  println(s"json = $json")

  val back = parser.fromJSON(json)
  println(s"back = $back")
}

获得与预期完全一样的输出。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM