uPickle和ScalaJS:密封特征序列化

时间:2015-02-20 14:01:01

标签: scala serialization scala.js upickle

我试图找到一个基本的上瘾的例子来工作,似乎我在这里遗漏了一些东西。我想试试the readme page for upickle

上提供的示例
import upickle._

sealed trait A
@key("Bee") case class B(i: Int) extends A
case object C extends A

然后,我的代码是:

object Model {
  def main(args: Array[String]): Unit = {

    val a = B(5): A
    println(a)

    val out = write(a)
    println(out)

    val a2 = read[A](out)
    println(a2)

    println(a == a2)

  }
}

我得到的只是错误:

  

引用的特征[[A]]没有任何子类。这可能   由于scalac(SI-7046)的限制而发生,因为该特征是   不在同一个包装中。如果是这种情况,则层次结构可能是   使用整数常量定义。

我有两个问题:

  • 我怎样才能说服uPickle这个特性在同一个包中? (因为它。)
  • 或者如果我不能:如何用整数常量定义层次结构?

2 个答案:

答案 0 :(得分:8)

您是否曾经遇到过这样的问题,你可以在这样的问题上花费多个小时,并且在询问StackOverflow问题后几分钟就解决了?

事实证明,由于compiler-specific details,这样一个密封的特征直到它定义的文件中的点之后才会知道它的直接子类。因此,在这种情况下,我已经定义了特征及其在之后主要方法的案例,其中up​​ickle将进行宏扩展和魔术。此时,它不会知道特征的情况。如果在定义特征及其案例之后将main方法移动到同一文件中,它将起作用。

答案 1 :(得分:2)

我在Scala.js项目中遇到此错误,我在服务器和客户端之间共享了一个密封的抽象类。

解决方案是使用Typelevel compiler而不是默认的Lightbend。

这很容易做到:

  1. 将其放入build.propertiessbt.version=0.13.13-M1
  2. 位于build.sbtscalaOrganization in ThisBuild:= "org.typelevel"
  3. 的顶部

    为了完整起见,这是我现在可以在客户端和服务器之间共享的类:

    sealed abstract class ServerResponse
    
    case class Ok(msg: String) extends ServerResponse
    
    case class Failure(msg: String) extends ServerResponse