在地图中使用 Enumeratum 枚举不起作用
Using an Enumeratum Enum in a Map does not work
我用 enumeratum 创建了一个枚举:
sealed trait Language extends EnumEntry
object Language
extends Enum[Language]
with PlayInsensitiveJsonEnum[Language] {
val values: IndexedSeq[Language] = findValues
case object DE extends Language
...
}
如果我在地图中使用它,它会抛出:
No instance of play.api.libs.json.Format is available for scala.collection.immutable.Map[finnova.bpf.api.entity.Language, java.lang.String] in the implicit scope (Hint: if declared in the same file, make sure it's declared before)
定义如下:
case class I18nEntry(values: Map[Language, String])
object I18nEntry {
implicit val jsonFormat: Format[I18nEntry] = Json.format[I18nEntry]
}
这里有效:
case class I18nEntry(values: Map[String, String], language: Language)
仅当您的 Map
键是 String
时,才会隐式提供 Map
的 Play Format
转换器,因为 JSON 对象键必须是字符串。它没有意识到 Language
是 最终 一个 String
(或者更确切地说,一个 JsString
)。因此,您需要为 Map[Language, String]
手动编写自己的 Reads
和 Writes
转换器,或者将 Language
映射到 String
键,例如您有 values: Map[String, String]
正如你在上面所做的那样。对于它的价值,第一个解决方案大致采用以下结构:
val langMapReads: Reads[Map[Language, String]] = ???
val langMapWrites: Writes[Map[Language, String]] = ???
implicit val langMapFormat: Format[Map[Language, String]] = Format(langMapReads, langMapWrites)
我用 enumeratum 创建了一个枚举:
sealed trait Language extends EnumEntry
object Language
extends Enum[Language]
with PlayInsensitiveJsonEnum[Language] {
val values: IndexedSeq[Language] = findValues
case object DE extends Language
...
}
如果我在地图中使用它,它会抛出:
No instance of play.api.libs.json.Format is available for scala.collection.immutable.Map[finnova.bpf.api.entity.Language, java.lang.String] in the implicit scope (Hint: if declared in the same file, make sure it's declared before)
定义如下:
case class I18nEntry(values: Map[Language, String])
object I18nEntry {
implicit val jsonFormat: Format[I18nEntry] = Json.format[I18nEntry]
}
这里有效:
case class I18nEntry(values: Map[String, String], language: Language)
仅当您的 Map
键是 String
时,才会隐式提供 Map
的 Play Format
转换器,因为 JSON 对象键必须是字符串。它没有意识到 Language
是 最终 一个 String
(或者更确切地说,一个 JsString
)。因此,您需要为 Map[Language, String]
手动编写自己的 Reads
和 Writes
转换器,或者将 Language
映射到 String
键,例如您有 values: Map[String, String]
正如你在上面所做的那样。对于它的价值,第一个解决方案大致采用以下结构:
val langMapReads: Reads[Map[Language, String]] = ???
val langMapWrites: Writes[Map[Language, String]] = ???
implicit val langMapFormat: Format[Map[Language, String]] = Format(langMapReads, langMapWrites)