我想从JSON字符串中提取案例类,并为每个类重用代码。 像this question这样的东西本来就很完美。但这意味着我必须为我想要提取的每个类写作。
我希望做类似的事情:
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{ ...}
我希望只要通过上限类型就可以重复使用fromJSON
和toJSON
class TwitterParser extends SocialMonitorParser[TwitterData] {
覆盖FromJSON} FacebookParser类扩展了SocialMonitorParser [FacebookData]
很有责任。
答案 0 :(得分:0)
我不确定您为什么要SocialMonitorParser
abstract
或Serializable
或者您将如何使用它?但如果您仔细观察错误,您可能会看到编译器需要Manifest
C
。 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")
}
以完全按照预期获得输出。