Scala 工具組

如何將物件序列化為 JSON?

語言

使用 Scala CLI,您可以在單一行中要求整個工具組

//> using toolkit latest

或者,您只要要求特定版本的 UPickle

//> using dep com.lihaoyi::upickle:3.1.0

在您的 build.sbt 檔案中,您可以新增對工具組的依賴關係

lazy val example = project.in(file("example"))
  .settings(
    scalaVersion := "3.2.2",
    libraryDependencies += "org.scala-lang" %% "toolkit" % "0.1.7"
  )

或者,您只要要求特定版本的 UPickle

libraryDependencies += "com.lihaoyi" %% "upickle" % "3.1.0"

在您的 build.sc 檔案中,您可以新增對 upickle 函式庫的依賴關係

object example extends ScalaModule {
  def scalaVersion = "3.2.2"
  def ivyDeps =
    Agg(
      ivy"org.scala-lang::toolkit:0.1.7"
    )
}

或者,您只要要求特定版本的 UPickle

ivy"com.lihaoyi::upickle:3.1.0"

將 Map 序列化為 JSON

uPickle 可以將您的 Scala 物件序列化為 JSON,以便您可以將它們儲存在檔案中或透過網路傳送它們。

預設情況下,它可以序列化基本類型,例如 IntString,以及標準集合,例如 MapList

val map: Map[String, Int] =
  Map("Toolkitty" -> 3, "Scaniel" -> 5)
val jsonString: String = upickle.default.write(map)
println(jsonString)
// prints: {"Toolkitty":3,"Scaniel":5}

將自訂物件序列化為 JSON

在 Scala 中,您可以使用 case class 來定義您自己的資料類型。例如,要表示寵物主人的寵物名稱,您可以

case class PetOwner(name: String, pets: List[String])

為了能夠將 PetOwner 寫入 JSON,我們需要提供一個 ReadWriter 實例,以供 case class PetOwner 使用。幸運的是,upickle 能夠完全自動化這項工作

import upickle.default._

implicit val ownerRw: ReadWriter[PetOwner] = macroRW[PetOwner]

一些說明

  • implicit val 是可以自動提供給方法或函式呼叫作為引數的值,而不需要明確傳遞它。
  • macroRW 是 uPickle 提供的方法,它可以使用 case class 的欄位資訊,為 case class 產生 ReadWriter 的實例。
import upickle.default.*

case class PetOwner(name: String, pets: List[String]) derives ReadWriter

derives 關鍵字用於自動產生給定的實例。使用編譯器對 PetOwner 中欄位的了解,它會產生 ReadWriter[PetOwner]

這表示您現在可以使用 upickle.default.write(petOwner)PetOwner 物件寫入 (及讀取) JSON。

請注意,您不需要將 ReadWriter[PetOwner] 的實例明確傳遞給 write 方法。但它仍然會從上下文中取得實例,作為「已提供」的值。您可以在 Scala 3 Book 中找到更多關於上下文抽象化的資訊。

將所有內容組合在一起,您應該會得到

import upickle.default._

case class PetOwner(name: String, pets: List[String])
implicit val ownerRw: ReadWriter[PetOwner] = macroRW

val petOwner = PetOwner("Peter", List("Toolkitty", "Scaniel"))
val json: String = write(petOwner)
println(json)
// prints: {"name":"Peter","pets":["Toolkitty","Scaniel"]}"
import upickle.default._

case class PetOwner(name: String, pets: List[String]) derives ReadWriter

val petOwner = PetOwner("Peter", List("Toolkitty", "Scaniel"))
val json: String = write(petOwner)
println(json)
// prints: {"name":"Peter","pets":["Toolkitty","Scaniel"]}"

此頁面的貢獻者