Как читать / писать универсальный класс с upickle - PullRequest
0 голосов
/ 24 января 2019

Скажем, у меня есть следующая черта:

trait T {
    val x: Int
}

def foo(i: Int): T

Я хотел бы поспорить, что смогу написать и прочитать эту черту, используя upickle, не зная, какой конкретно класс.Например:

upickle.default.write(foo(3))

Так что я мог бы в другом месте определить foo как что-то вроде:

case class A(x: Int)

def foo(i: Int): T = A(i)

Я думаю, мне нужно определить неявного Writer как члена T, но я нене знаете, какой будет синтаксис?

1 Ответ

0 голосов
/ 24 января 2019
trait T {
  val x: Int
}
object T {
  implicit val rw: ReaderWriter[T] = ...
}

Проблема в том, что поместить в часть ...: если у вас есть значение T, вы можете просто сохранить его x:

... = readwriter[Int].bimap[T](
  t => t.x,
  i => new T { val x = i }
)

Проблема с этим решением состоит в том, что чтение записанного A(3) не вернет A. И это на самом деле не решаемо без запечатывания T или какой-либо другой обработки только определенного набора подклассов.

Вы можете также включить имя класса при написании, но это не поможет, если в классе есть какие-либо поля, кроме x, для хранения:

class B(override val x: Int, y: String) extends T

Если T равен sealed, вы просто пишете

... = macroRW
...