2015-02-20 11 views
8

Tôi đang cố gắng để có được một ví dụ upickle cơ bản để làm việc và có vẻ như tôi đang thiếu một cái gì đó ở đây. Tôi muốn thử ra các ví dụ được cung cấp trên the readme page for upickleuPickle và ScalaJS: serialization đặc tính kín

import upickle._ 

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

Sau đó, mã của tôi là:

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) 

    } 
} 

Tất cả tôi nhận được là lỗi:

The referenced trait [[A]] does not have any sub-classes. This may happen due to a limitation of scalac (SI-7046) given that the trait is not in the same package. If this is the case, the hierarchy may be defined using integer constants.

Tôi có hai câu hỏi:

  • Làm cách nào tôi có thể thuyết phục được uPickle tha t các đặc điểm là trong cùng một gói? (Vì nó là.)
  • Hoặc nếu tôi không thể: làm thế nào tôi có thể xác định thứ bậc với hằng số nguyên?

Trả lời

8

Đã từng có hội chứng mà bạn có thể dành nhiều giờ cho một vấn đề như thế này và bạn giải quyết nó sau khi hỏi câu hỏi StackOverflow?

Nó chỉ ra rằng do compiler-specific details, một đặc điểm kín như vậy sẽ không biết các lớp con trực tiếp của nó cho đến sau thời điểm tệp được xác định. Vì vậy, trong trường hợp này, tôi đã xác định đặc điểm và các trường hợp của nó sau phương pháp chính, nơi upickle sẽ làm việc mở rộng macro và phép thuật của nó. Tại thời điểm này, nó sẽ không biết về các trường hợp của đặc điểm. Nếu phương pháp chính được di chuyển trong cùng một tệp sau khi định nghĩa đặc điểm và các trường hợp của nó, nó sẽ hoạt động.

+1

Mã của tôi đã hoạt động tốt cho đến khi tôi đổi tên gói mà đặc điểm/lớp con của tôi đã có. Vì lý do nào đó, chúng phải được biên dịch theo một thứ tự khác. Tôi đã nghiêm túc gãi đầu. Cám ơn vì cái này. –

2

Tôi đã gặp lỗi này trong dự án Scala.js, nơi tôi chia sẻ lớp trừu tượng được niêm phong giữa máy chủ và ứng dụng khách.

Giải pháp là sử dụng Typelevel compiler thay vì giá Lightbend mặc định.

này có thể dễ dàng thực hiện:

  1. Đặt này trong thư mục build.properties: sbt.version=0.13.13-M1
  2. và điều này ở đầu build.sbt của bạn: scalaOrganization in ThisBuild:= "org.typelevel"

Đối với đầy đủ lợi ích, điều này là lớp tôi có thể chia sẻ giữa khách hàng và máy chủ:

sealed abstract class ServerResponse 

case class Ok(msg: String) extends ServerResponse 

case class Failure(msg: String) extends ServerResponse 
Các vấn đề liên quan