繁体   English   中英

Scala类型类了解接口语法

[英]Scala Type Classes Understanding Interface Syntax

我正在阅读有关猫的信息,并且遇到了以下有关将对象序列化为JSON的代码片段!

它以这样的特征开始:

trait JsonWriter[A] {
  def write(value: A): Json
}

此后,我们的域对象有一些实例:

final case class Person(name: String, email: String)

object JsonWriterInstances {
  implicit val stringWriter: JsonWriter[String] =
    new JsonWriter[String] {
      def write(value: String): Json =
        JsString(value)
    }

  implicit val personWriter: JsonWriter[Person] =
    new JsonWriter[Person] {
      def write(value: Person): Json =
        JsObject(Map(
          "name" -> JsString(value.name),
          "email" -> JsString(value.email)
        ))
    }
  // etc...
}

到现在为止还挺好! 然后,我可以这样使用:

import JsonWriterInstances._
Json.toJson(Person("Dave", "dave@example.com"))

稍后,我遇到了一种称为接口语法的东西,该语法使用扩展方法通过如下所示的接口方法来扩展现有类型:

object JsonSyntax {
  implicit class JsonWriterOps[A](value: A) {
    def toJson(implicit w: JsonWriter[A]): Json =
      w.write(value)
  }
}

然后,这简化了将Person序列化为的调用:

import JsonWriterInstances._
import JsonSyntax._
Person("Dave", "dave@example.com").toJson

我不明白的是,如何将Person装箱到JsonWriterOps中,这样我就可以直接调用toJson,就像toJson是在Person案例类本身中定义的一样。 我喜欢这种魔术,但是我无法理解关于JsonWriterOps的最后一步。 那么,该接口语法背后的思想是什么?它如何工作? 有什么帮助吗?

这实际上是Scala的标准功能,因为JsonWriterOps被标记为implicit且在范围内,因此编译器可以在需要时在编译时应用它。 因此,scalac将执行以下转换:

Person("Dave", "dave@example.com").toJson
new JsonWriterOps(Person("Dave", "dave@example.com")).toJson
new JsonWriterOps[Person](Person("Dave", "dave@example.com")).toJson

旁注

将隐式类作为值类的效率要高得多,如下所示:

implicit class JsonWriterOps[A](value: A) extends AnyVal

这使得编译器还优化了新对象的构造,如果可能的话,将整个隐式转换+方法调用编译为一个简单的函数调用。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM