簡體   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