【问题标题】:In Scala, how to create a trait for classes with functions using different context bounds在 Scala 中,如何为具有使用不同上下文边界的函数的类创建特征
【发布时间】:2017-09-25 23:18:25
【问题描述】:

现在我想序列化/反序列化 Json 数据,有几个 json 库可供选择。但是,它们使用不同的上下文边界进行编码/解码,这使得为它们定义特征变得困难。

trait JsonLib {
  // def writes[T](data: T): String
  // def reads[T](jsonStr: String): Option[T]
}

object JsonCirce extends JsonLib {
  import io.circe.Encoder._
  import io.circe.Decoder._

  def writes[T: Encoder](data: T): String = ...
  def reads[T: Decoder](jsonStr: String): Option[T] =
}

//spray-json
object JsonSpray extends JsonLib {
  import spray.json._

  def writes[T: JsonWriter](data: T): String = ...

  def reads[T: JsonReader](jsonStr: String): Option[T] = ...
}

有没有办法在 trait 中定义写入/读取?

【问题讨论】:

  • 您想通用定义一个接受来自多个库的多个编码器/解码器的特征?如果是这样,介意我问你为什么需要多个序列化库?
  • 我们有一个很大的 Json,序列化时间对于 web 服务很重要,所以我写了一个基准来测试不同库的性能。
  • 该服务与其他一些服务进行通信,所以我想要所有数据类型的通用特征,而不是为每种数据类型编写 JsonLib 特征。
  • 如果这是用于性能测试,我会避免使用泛型的开销,并使用普通的旧方法调用来测试每​​个库。不要介意重复的代码。
  • 听起来很公平。不过,泛化泛型方法是一个有趣的话题。

标签: scala traits context-bound


【解决方案1】:

您可以使用更高种类的类型来概括类型类,例如:

import scala.language.higherKinds
import scala.util.Try
import spray.json._
import DefaultJsonProtocol._

trait JsonLib[R[_], W[_]] {
  def writes[T: W](data: T): String

  def reads[T: R](jsonStr: String): Option[T]
}

//spray-json
object JsonSpray extends JsonLib[JsonReader, JsonWriter] {

  override def writes[T: JsonWriter](data: T): String =
    data.toJson.compactPrint

  override def reads[T: JsonReader](jsonStr: String): Option[T] =
    Try(jsonStr.parseJson.convertTo[T]).toOption
}

// Test
JsonSpray.writes(List(1, 2))
JsonSpray.reads[List[Int]]("[1,2]")

【讨论】:

  • 是的,这正是我想知道的。谢谢!
猜你喜欢
  • 1970-01-01
  • 2016-10-18
  • 1970-01-01
  • 1970-01-01
  • 2016-07-17
  • 2017-02-01
  • 2022-11-16
  • 2012-08-28
  • 2020-12-21
相关资源
最近更新 更多