给定select f1,f2,sum(f2) over(order by f1) running_total, Floor(sum(f2) over(order by f1) / 40) [rank]
from [dbo].[Sheet1$]
类带有'智能构造函数',即Person
中只有“有效”值会构造Person#build
:
Person
我将case class Person private(age: Int)
object Person {
def build(age: Int): Option[Person] =
if (age >= 0 && age <= 125) Some(Person(age)) else None
}
放入Reads[Person]
的伴侣对象中创建了Person
:
import play.api.libs.json._
import play.api.libs.functional.syntax._
implicit val reads: Reads[Person] =
(__ \ 'age).read[Int].map(a =>
Person.build(a).getOrElse(throw new RuntimeException("invalid age")
)
有更好的方法吗?如果可能的话,我宁愿避免这种例外。
答案 0 :(得分:2)
如果您愿意放弃播放功能样式,可以使用JsResult
monad:
new Format[Person] {
override def writes(o: Person): JsValue = ???
override def reads(json: JsValue): JsResult[Person] = {
try{
json.as[JsObject].value.get("age")
.flatMap(age => Person.build(age.as[Int])).map(JsSuccess(_))
.getOrElse(JsError("wrong age"))
} catch {
case e: Exception =>
JsError("wrong age")
}
}
}
val person = Json.toJson(Person.build(30))
val parsed: \/[String, Person] = person.validate[Person].map(\/-(_)).getOrElse(-\/("some bad request"))
所以它比我在评论中建议的要复杂一点,但基本上你可以将解析包装成一个方法,将JsSuccess
转换为右边,将JsError
转换为左边, try/catch
我用来捕捉发送的json不是一个对象而只是一个值或者如果age字段不是整数的情况。