首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >如何基于富集动态调度?

如何基于富集动态调度?
EN

Stack Overflow用户
提问于 2012-05-27 06:47:08
回答 2查看 222关注 0票数 2

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

代码语言:javascript
运行
复制
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
}

理想情况下,我更喜欢这样的(不可能的)东西:

代码语言:javascript
运行
复制
def maybeJson2(any: Any): Option[JsValue] = {
  if (pimpExistsFor(any))
    Some(any.toJson)
  else
    None  
}

有没有一种方法可以做到这一点,而不是枚举每一种已经被丰富的类型?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2012-05-27 07:33:20

有一种方法,但它需要大量的思考,因此是相当令人头疼的。其基本思想如下。DefaultJsonProtocol对象继承了一组包含隐式对象的特征,这些隐式对象包含write方法。每一个都有一个存取器函数,但是你不知道它叫什么。基本上,您只需获取所有不带参数的方法,并返回一个具有write方法的对象,该方法获取对象的类并返回JsValue。如果您只找到一个这样的方法返回一个这样的类,请使用反射来调用它。否则,保释。

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

代码语言:javascript
运行
复制
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)
    }
  }
}

无论如何,您最好逐步拆分REPL中的DefaultJsonProtocol类,并了解如何可靠地识别定义编写器的对象,然后从中获取write方法。

票数 3
EN

Stack Overflow用户

发布于 2012-05-27 19:39:54

我不确定它是否能满足您的需要,但这里有一个非常简单且类型安全的替代方法。

如果您保留参数的类型(而不是使用Any),则可以依靠隐式参数解析在编译时找到正确的转换:

代码语言:javascript
运行
复制
def toJson[T:JsonFormat]( t: T ): JsValue = implicitly[JsonFormat[T]].write(t)

你不需要一个选项,因为如果你试图传递一个不是"pimpable“的参数,程序将在编译时失败。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/10770344

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档