scala风格 – 如何避免大量的嵌套地图
发布时间:2020-12-16 09:19:16 所属栏目:安全 来源:网络整理
导读:在验证多个连续性条件时,我经常会遇到很多嵌套的.map和.getOrElse 例如: def save() = CORSAction { request = request.body.asJson.map { json = json.asOpt[Feature].map { feature = MaxEntitiyValidator.checkMaxEntitiesFeature(feature).map { rs = f
在验证多个连续性条件时,我经常会遇到很多嵌套的.map和.getOrElse
例如: def save() = CORSAction { request => request.body.asJson.map { json => json.asOpt[Feature].map { feature => MaxEntitiyValidator.checkMaxEntitiesFeature(feature).map { rs => feature.save.map { feature => Ok(toJson(feature.update).toString) }.getOrElse { BadRequest(toJson( Error(status = BAD_REQUEST,message = "Error creating feature entity") )) } }.getOrElse { BadRequest(toJson( Error(status = BAD_REQUEST,message = "You have already reached the limit of feature.") )) } }.getOrElse { BadRequest(toJson( Error(status = BAD_REQUEST,message = "Invalid feature entity") )) } }.getOrElse { BadRequest(toJson( Error(status = BAD_REQUEST,message = "Expecting JSON data") )) } } 你得到这个想法 我只是想知道是否有一些惯用的方法来保持更清楚 解决方法
如果您没有为None案例返回不同的消息,这将是理解的理想用例.在你的情况下,你可能想要使用验证monad,就像在Scalaz中找到的那样.示例(
http://scalaz.github.com/scalaz/scalaz-2.9.0-1-6.0/doc.sxr/scalaz/Validation.scala.html).
在函数式编程中,不应该抛出异常,而是让失败的函数返回一个[A,B],其中按照惯例A是失败时的结果类型,B是成功时的结果类型.然后,您可以与左(a)或右(b)匹配来对两种情况进行反复处理. 您可以将验证monad视为扩展名[A,其中将后续功能应用于验证将产生结果或执行链中的第一个失败. sealed trait Validation[+E,+A] { import Scalaz._ def map[B](f: A => B): Validation[E,B] = this match { case Success(a) => Success(f(a)) case Failure(e) => Failure(e) } def foreach[U](f: A => U): Unit = this match { case Success(a) => f(a) case Failure(e) => } def flatMap[EE >: E,B](f: A => Validation[EE,B]): Validation[EE,B] = this match { case Success(a) => f(a) case Failure(e) => Failure(e) } def either : Either[E,A] = this match { case Success(a) => Right(a) case Failure(e) => Left(e) } def isSuccess : Boolean = this match { case Success(_) => true case Failure(_) => false } def isFailure : Boolean = !isSuccess def toOption : Option[A] = this match { case Success(a) => Some(a) case Failure(_) => None } } final case class Success[E,A](a: A) extends Validation[E,A] final case class Failure[E,A](e: E) extends Validation[E,A] 您的代码现在可以通过将验证单元用于三个验证层来重构.您应该基本上用以下验证来替换地图: def jsonValidation(request:Request):Validation[BadRequest,String] = request.asJson match { case None => Failure(BadRequest(toJson( Error(status = BAD_REQUEST,message = "Expecting JSON data") ) case Some(data) => Success(data) } def featureValidation(validatedJson:Validation[BadRequest,String]): Validation[BadRequest,Feature] = { validatedJson.flatMap { json=> json.asOpt[Feature] match { case Some(feature)=> Success(feature) case None => Failure( BadRequest(toJson( Error(status = BAD_REQUEST,message = "Invalid feature entity") ))) } } } 然后你链接他们像以下featureValidation(jsonValidation(请求)) (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |