Вот более функциональная версия вашего кода.Он определяет объект с помощью метода apply
, который можно использовать так же, как и исходную функцию.
object parseJson {
private def parseAsString(runSnap: String): Map[Long, Object] =
Try {
JSONUtils.parseByFastJson(runSnap).asScala
.toMap.map(entry => entry._1.toLong -> entry._2)
} match {
case Success(result) =>
result
case _ =>
parser = parseAsLong _
parser(runSnap)
}
private def parseAsLong(runSnap: String): Map[Long, Object] =
Try {
JSONUtils. parseByFastJsonLongKey(runSnap).asScala
.toMap.map(entry => Long2long(entry._1.toLong) -> entry._2)
}.getOrElse(Map[Long, Object]())
private val parser = parseAsString _
def apply(runSnap: String) = parser(runSnap)
}
Первоначально parser
имеет значение parseAsString
, поэтому apply
вызывает parseAsString
, что вызывает parseByFastJson
.Но когда синтаксический анализ не выполняется в parseAsString
, он устанавливает parser
в parseAsLong
.Последующие звонки на apply
вызовут parseAsLong
, который вместо этого вызовет parseByFastJsonLongKey
.Единственный раз, когда обе JSON-функции вызываются, первый раз parseByFastJson
завершается неудачно.После этого parseByFastJsonLongKey
вызывается напрямую parseAsLong
.
Использование объекта скрывает var
, а сохранение функции в var
является более чистым и эффективным, чем тестирование String
каждый раз.