1

我正在使用 uPickle 1.2.0。我有这个示例代码:

import upickle._
import upickle.default._
import upickle.implicits.key

sealed trait Field

@key("TypeA") case class TypeA(val valueA: Int) extends Field
@key("TypeB") case class TypeB(val valueB: String) extends Field
@key("TypeC") case class TypeC(val valueC: List[Int]) extends Field

object Field {
  implicit val rA: Reader[TypeA] = macroR
  implicit val rB: Reader[TypeB] = macroR                             
  implicit val rC: Reader[TypeC] = macroR
  implicit val rField: Reader[Field] = Reader.merge(rA, rB, rC)
}                                                                       

object Main {
  def main(args: Array[String]) {
    import Field._        
                                            
    val example_json = """
      [ { "$type": "TypeA", "valueA": 123 },
        { "$type": "TypeB", "valueB": "123string" },
        { "$type": "TypeC", "valueC": [1,2,3] } ]"""   

    read[List[Field]](example_json).foreach(println(_))
  }                                                                     
}

它工作正常。但是,假设我只想创建一个自定义选择器,为andTypeB保留默认选择器。这在 uPickle 中可行吗?我正在尝试使用传统方法,该方法适用于简单(未键入)的字段:TypeATypeC

// change this:
//
// implicit val rB: Reader[TypeB] = macroR                             
//
// to this:

  implicit val rB: Reader[TypeB] = reader[ujson.Value].map[TypeB] { j =>
    TypeB(j.obj("valueB").str)
  }

这编译得很好,但在运行时抛出异常:

[E] Exception in thread "main" java.lang.ClassCastException: class upickle.core.Types$Reader$$anon$4 cannot be cast to class upickle.core.Types$TaggedReader (upickle.core.Types$Reader$$anon$4 and upickle.core.Types$TaggedReader are in unnamed module of loader 'app')
[E]     at upickle.core.Types.upickle$core$Types$$scanChildren(Types.scala:241)
[E]     at upickle.core.Types$TaggedReader$Node.findReader(Types.scala:258)
[E]     at upickle.AttributeTagged$$anon$4.visitValue(Api.scala:240)
[E]     at ujson.Parser.rparse(Parser.scala:429)
[E]     at ujson.Parser.parse(Parser.scala:346)
[E]     at ujson.Parser.parse(Parser.scala:339)
[E]     at ujson.Parser.parse(Parser.scala:339)
[E]     at ujson.Parser.parse(Parser.scala:339)
[E]     at ujson.Parser.parse(Parser.scala:339)
[E]     at ujson.Parser.parse(Parser.scala:339)
[E]     at ujson.Parser.parse(Parser.scala:339)
[E]     at ujson.Parser.parse(Parser.scala:342)
[E]     at ujson.Parser.parse(Parser.scala:104)
[E]     at ujson.StringParser$.transform(StringParser.scala:29)
[E]     at ujson.StringParser$.transform(StringParser.scala:28)
[E]     at ujson.Readable$fromTransformer.transform(Readable.scala:13)
[E]     at upickle.Api.$anonfun$read$1(Api.scala:40)
[E]     at upickle.core.TraceVisitor$.withTrace(TraceVisitor.scala:20)
[E]     at upickle.Api.read(Api.scala:40)
[E]     at upickle.Api.read$(Api.scala:39)
[E]     at upickle.default$.read(Api.scala:131)
[E]     at Main$.main(Main.scala:30)
[E]     at Main.main(Main.scala)

uPickle 支持吗?我应该以不同的方式为标记类定义自定义pickler吗?我在文档中没有看到我的案例的任何示例。

4

0 回答 0