更具可读性的scala模式用于匹配成功

更具可读性的scala模式用于匹配成功,scala,scala-2.9,Scala,Scala 2.9,我发现成功的例子常常被许多错误和一次成功所掩盖。有没有另一种方法可以写得更清楚,这样成功就可以通过在部分函数中包含所有错误而脱颖而出?或者,也许有另一种方式写它,但只是更干净。总的来说,我只是在寻找其他可以实现的想法/解决方案 results.responseCode match { case Success => // TODO make this less smelly. can results.results be None? val searchResults

我发现成功的例子常常被许多错误和一次成功所掩盖。有没有另一种方法可以写得更清楚,这样成功就可以通过在部分函数中包含所有错误而脱颖而出?或者,也许有另一种方式写它,但只是更干净。总的来说,我只是在寻找其他可以实现的想法/解决方案

results.responseCode match {
  case Success =>
    // TODO make this less smelly. can results.results be None?
    val searchResults = results.results.get.results
    SomeService.getUsersFromThriftResults(
      userRepo,
      searchResults,
      Seq(WithCounts)) map { userResults =>
      val renderableStatuses = getStatuses(searchResults, userResults.userMap)
      new JsonAction(transformedQuery, renderableStatuses)
    }
  case ErrorInvalidQuery =>
    throw new SomeBadRequestException("invalid query")
  case ErrorOverCapacity |
       ErrorTimeout =>
    throw new SomeServiceUnavailableException("service unavailable")
  //TODO: take care of these errors differently
  //          case ErrorInvalidWorkflow |
  //               ErrorBackendFailure |
  //               ErrorEventNotFound |
  //               PartialSuccess |
  case _ =>
    throw new SomeApplicationException("internal server error")
}

您应该考虑使用[抛出,A]来表示结果类型。


您可以将结果转换为[ResponseCode,Content]

def codeToEither(result: Result): Either[ResponseCode, Content] = 
  result.responseCode match {
    case Success => Right(result.results.get.results)
    case _       => Left(result.responseCode)
  }
然后将折叠起来

codeToEither(result).fold(
  errorCode => ... ,
  content   => ...
)
如果您愿意,也可以用同样的方法将结果转换为[code>或[Exception,Content]。

您可以尝试

文档中的示例:

import scala.util.{Try, Success, Failure}

def divide: Try[Int] = {
  val dividend = Try(Console.readLine("Enter an Int that you'd like to divide:\n").toInt)
  val divisor = Try(Console.readLine("Enter an Int that you'd like to divide by:\n").toInt)
  val problem = dividend.flatMap(x => divisor.map(y => x/y))
  problem match {
    case Success(v) =>
      println("Result of " + dividend.get + "/"+ divisor.get +" is: " + v)
      Success(v)
    case Failure(e) =>
      println("You must've divided by zero or entered something that's not an Int. Try again!")
      println("Info from the exception: " + e.getMessage)
      divide
  }
}

您可以使用
orElse
链接部分函数

差不多

type ResponseCode = Int // This would be the type of the results.responseCode.
type RespHandler = PartialFunction[ResponseCode, JsonAction]

val invalidQuery: RespHandler =
  { case ErrorInvalidQuery => ... }

val overCapacity: RespHandler =
  { case ErrorOverCapacity => ... }

results.responseCode match {
  case Success => ...
} orElse invalidQuery orElse overCapacity orElse ...
你可以在这篇博文中看到更多信息:

编辑:这不能像编写的那样工作,您需要编写处理,然后应用它(例如
(success或lse invalidQuery…)(results.getResponseCode)


更好的解决方案是将其更改为返回
Try[ResponseCode]
并在
失败
匹配块中处理异常。

net.databinder.dispatch库提供了一个接口,可以为您提供一个两者都可以的选项。我不明白为什么平面版本还不是很好和简单。如果您能够更改API,您仍然应该使用
Try
或类似的选项。这是错。比赛的案例块不是PF,尽管它看起来像PF。我想没有人把这个输入REPL?诚然,您可以将PFs链接为
(a或b)(x)
;或者您可以注释应该验证代码段;也许OP只能请求经过验证的代码片段。你是对的,那是行不通的。我在《catch》中看到了它,我想你也可以在《match》中看到它。