Json.fromJson、as、asOpt 和 validate 之间有什么区别?

What's the difference between Json.fromJson, as, asOpt and validate?

如果我有一个 JsValue,我应该使用哪种方法从 JsValue 中获取值:Json.fromJsonasasOptvalidate?

这取决于您想要的错误处理级别。

asasOptvalidate 的共同点是它们会尝试将 JsValue 反序列化为类型 T 你指定,使用任何隐式 Reads[T] 可以解决。它们的不同之处在于它们的行为方式以及它们的类型 return.

假设我们正在使用 class Foo,其中我们已经定义了一个隐式 Reads[Foo]

as[Foo] 将简单地尝试将 JsValue 转换为 Foo,如果失败,则会抛出异常。这不是一件安全的事情,因为处理错误的唯一方法是捕获异常并处理它,您可能不记得这样做了。 JSON 无法映射到特定类型很少是例外情况,或者它一直都在发生。 as 应该很少使用,最多。

asOpt[Foo] 将尝试将 JsValue 转换为 Foo,如果失败,它将简单地 return None。如果成功,它将 return 包装在 Some 中的反序列化值。这比 as 好得多,因为你被迫面对失败案例(除非你做了一些愚蠢的事情,比如调用 .get)。缺点是,将失败转换为 None 时,所有错误都被吞没了,因此您不知道失败的原因。如果您不在乎,使用 asOpt 完全没问题。

validate[Foo] 将尝试将 JsValue 转换为 Foo,并且总是 return 为 JsResult[Foo]。如果转换成功,它将是一个包含反序列化值的 JsSuccess[Foo]。如果失败,它将是一个 JsError ,其中包含所有错误信息,例如缺少哪些路径以及哪些类型与预期不匹配。您可以在 JsResult 上使用 fold 方法来安全地处理每种情况。例如:

js.validate[Foo].fold(
  errors => /* Do something with the errors */ ,
  foo => /* Do something with Foo */
)

Json.fromJson 做与 JsValue#validate 完全相同的事情。他们都称底层 Reads 到 return 为 JsResult.