[英]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.