scala – 如何改进“嵌套Try .. match”的代码?

前端之家收集整理的这篇文章主要介绍了scala – 如何改进“嵌套Try .. match”的代码?前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
在我的 scala代码中,我有一些嵌套的Try()匹配{},看起来很难看:

import scala.util._

Try(convertJsonToObject[User]) match {
  case Success(userJsonObj) =>
    Try(saveToDb(userJsonObj.id)) match {
      case Success(user) => Created("User saved")
      case _ => InternalServerError("database error")
    }
  case _ => BadRequest("bad input")
}

有没有更好的方法来编写这样的代码

解决方法

有很多方法可以解决这个问题.我会给你一个可能性.考虑这个清理过的代码版本:

trait Result
case class BadRequest(message:String) extends Result
case class InternalServerError(message:String) extends Result
case class Created(message:String) extends Result

def processRequest(json:String):Result = {
  val result = 
    for{
      user <- Try(parseJson(json))
      savedUser <- Try(saveToDb(user))
    } yield Created("saved")

  result.recover{
    case jp:JsonParsingException => BadRequest(jp.getMessage)
    case other => InternalServerError(other.getMessage)
  }.get
}

def parseJson(json:String):User = ...
def saveToDb(user:User):User = ...

对此代码的警告是,它假定您可以通过每个可能产生的异常来区分json解析失败和db失败.虽然做出了不错的假设.此代码与java try / catch块非常相似,它捕获不同的异常类型,并根据捕获这些不同类型返回不同的结果.

关于这种方法的另一个好处是你可以为各种可能的异常定义一个标准的恢复部分函数,​​并在整个控制器中使用它(我假设这个代码是)来消除重复的代码.像这样的东西:

object ExceptionHandling{
  val StandardRecovery:PartialFunction[Throwable,Result] = {
    case jp:JsonParsingException => BadRequest(jp.getMessage)
    case sql:sqlException => InternalServerError(sql.getMessage)
    case other => InternalServerError(other.getMessage)   
  }
}

然后在你的控制器中:

import ExceptionHandling._
result.recover(StandardRecovery).get

猜你在找的Scala相关文章