gpt4 book ai didi

json - 如何基于浓缩动态调度?

转载 作者:行者123 更新时间:2023-12-04 05:45:12 24 4
gpt4 key购买 nike

spray-json库使用 toJson 扩展了基本的 Scala 类型方法。我想转换 Any JsValue 如果底层类型有这样的皮条客。我最好的尝试有效,但很冗长:

import cc.spray._

val maybeJson1: PartialFunction[Any, JsValue] = {
case x: BigDecimal => x.toJson
case x: BigInt => x.toJson
case x: Boolean => x.toJson
case x: Byte => x.toJson
case x: Char => x.toJson
case x: Double => x.toJson
case x: Float => x.toJson
case x: Int => x.toJson
case x: Long => x.toJson
case x: Short => x.toJson
case x: String => x.toJson
case x: Symbol => x.toJson
case x: Unit => x.toJson
}

理想情况下,我更喜欢这样的事情(不可能):
def maybeJson2(any: Any): Option[JsValue] = {
if (pimpExistsFor(any))
Some(any.toJson)
else
None
}

有没有办法在不枚举每个已经丰富的类型的情况下做到这一点?

最佳答案

有一个方法,但是它需要大量的反射(reflection),因此很头疼。基本思想如下。 DefaultJsonProtocol object 继承了一堆包含隐式对象的特征,其中包含 write方法。每一个都有一个访问器函数,但你不会知道它叫什么。基本上,您只需采用所有不带参数的方法并返回一个具有 write 的对象。获取对象类并返回 JsValue 的方法.如果您发现恰好一个这样的方法返回一个这样的类,请使用反射来调用它。否则,保释。

它看起来像这样(警告,未经测试):

def canWriteMe(writer: java.lang.Class[_], me: java.lang.Class[_]): 
Option[java.lang.reflect.Method] =
{
writer.getMethods.find(_.getName == "write").filter{ m =>
classOf[JsValue].isAssignableFrom(m.getReturnType) && {
val parm = m.getParameterTypes()
m.length == 1 && parm(0).isAssignableFrom(me)
}
}
}
def maybeJson2(any: Any): Option[JsValue] = {
val couldWork = {
DefaultJsonProtocol.getClass.getMethods.
filter(_.getParameterTypes.length==0).
flatMap(m => canWriteMe(m.getReturnType, any.getClass).map(_ -> m))
}
if (couldWork.length != 1) None else {
couldWork.headOption.map{ case (wrMeth, obMeth) =>
val wrObj = obMeth.invoke(DefaultJsonProtocol)
val answer = wrMeth.invoke(wrObj, any)
}
}
}

无论如何,你最好拔掉 DefaultJsonProtocol在 REPL 中一步一步地将类分开,找出如何可靠地识别定义作者的对象,然后得到 write他们的方法。

关于json - 如何基于浓缩动态调度?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10770344/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com