我是 Scala 的新手,想学习解决常见问题的惯用方法,例如 Python 的 pythonic。我的问题是关于使用upickle读取 JSON 数据,其中 JSON 值在存在时包含字符串,在不存在时包含 null。我想使用自定义值来替换 null。一个简单的例子:
import upickle.default._
val jsonString = """[{"always": "foo", "sometimes": "bar"}, {"always": "baz", "sometimes": null}]"""
val jsonData = ujson.read(jsonString)
for (m <- jsonData.arr) {
println(m("always").str.length) // this will work
println(m("sometimes").str.length) // this will fail, Exception in thread "main" ujson.Value$InvalidData: Expected ujson.Str (data: null)
}
问题在于字段"sometimes"
:当为 null 时,我们不能应用.str
(或任何其他函数映射到除 null 之外的静态类型)。我正在寻找类似的东西, null 的替代品m("sometimes").str("DEFAULT").length
在哪里。"DEFAULT"
想法 1 使用模式匹配,以下工作:
val sometimes = m("sometimes") match {
case s: ujson.Str => s.str
case _ => "DEFAULT"
}
println(sometimes.length)
鉴于 Scala 的简洁语法,这看起来有点复杂,并且在处理多个值时会重复。
想法 2 对相关问题的回答提到创建具有默认值的案例类。对于我的问题,当根据上下文需要不同的替换值时,案例类的创建对我来说似乎不灵活。
Idea 3
Anwers to another question (not specific to upickle)讨论使用Try().getOrElse()
,即:
import scala.util.Try
// ...
println(Try(m("sometimes").str).getOrElse("DEFAULT").length)
但是,讨论提到为常规程序路径抛出异常是昂贵的。
解决这个问题的惯用但简洁的方法是什么?