【问题标题】:JSON of object of type Any and a TypeTagAny 类型对象的 JSON 和 TypeTag
【发布时间】:2016-07-18 07:29:27
【问题描述】:

给定一个 Any 类型的对象及其 TypeTag,如何使用 Argonaut/Shapeless 创建它的 JSON?

  case class Person(name: String, age: Int)

  // somewhere in the code where type of 'any' is known,
  // and we preferrably dont want to include information
  // about JSON capabilities (i.e. prefer not to include
  // implicit EncodeJson[Person])
  val tt = typeTag[Person].asInstanceOf[TypeTag[Any]]
  val any = Person("myname", 123).asInstanceOf[Any]

  //somewhere else in the code where type of 'any' is unknown, but we got the TypeTag 'tt'
  implicit val e: EncodeJson[ ??? ] = ??? //somehow utilize 'tt' here?
  println(any.asJson)

【问题讨论】:

  • 我认为不使用反射是不可能的,即编译时类型安全。一旦您将类型标记转换为TypeTag[Any],编译器就不能再使用它来解析隐含的EncodeJson 值。如果您想将 JSON 编码与域对象分离,您可以考虑使用类型类。但是,一旦您将域对象转换为 Any,无论如何您都会迷失方向,您可以使用 match/case 语句根据运行时类型为您的对象选择 EncodeJson val。
  • 我明白了。希望避免这种情况。如果一个人确实接受了某种程度的反射,那么如何获得一个合适的 EncodeJson 的实例呢?我正在考虑 ArgonautShapeless 'EncodeJson.of[T]',但我不知道它是否适用于运行时。
  • 经过更多研究,似乎不可能在运行时解析隐式参数。有toolbox.inferImplicitValue (groups.google.com/forum/#!topic/scala-internals/…),但我认为这也无济于事。我建议保留对象的EncodeJson 信息。
  • @devkat 听从您的建议。如果您在答案中发布您的发现,我会接受。

标签: scala shapeless argonaut argonaut-shapeless


【解决方案1】:

我认为如果不使用反射,即使用编译时类型安全,这是不可能的。一旦您将类型标记转换为TypeTag[Any],编译器就不能再使用它来解析隐含的EncodeJson 值。据我所知,在运行时解析隐式参数是不可能的。有toolbox.inferImplicitValue,但我认为这也无济于事。

如果您知道所有可能的类型,则可以使用 match/case 语句根据运行时类型为您的对象选择 EncodeJson val,并显式传递它。

不过,我建议保留对象的 EncodeJson 信息。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-05-22
    • 1970-01-01
    • 2016-04-27
    • 1970-01-01
    • 2017-07-03
    • 2017-02-23
    • 1970-01-01
    相关资源
    最近更新 更多