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,我们需要为 case class PetOwner 提供一个 ReadWriter 实例。幸运的是,upickle 能够完全自动化

import upickle.default._

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

一些解释

  • 一个 implicit val 是一个值,它可以作为方法或函数调用的一个参数自动提供,而无需显式传递它。
  • macroRW 是 uPickle 提供的一个方法,它可以使用有关其字段的信息为 case 类生成 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"]}"

此页面的贡献者