Scala偏函数的奇怪错误

Scala偏函数的奇怪错误,scala,Scala,由于某种奇怪的原因,我有下面的代码无法编译 def createNewPowerPlant = Action.async(parse.tolerantJson) { request => request.body.validate[PowerPlantConfig].fold( errors => { Future.successful( BadRequest(Json.obj("message" -> s"invalid

由于某种奇怪的原因,我有下面的代码无法编译

def createNewPowerPlant = Action.async(parse.tolerantJson) { request =>
    request.body.validate[PowerPlantConfig].fold(
      errors => {
        Future.successful(
          BadRequest(Json.obj("message" -> s"invalid PowerPlantConfig $errors"))
        )
      },
      success => { // fails here!!
        dbService.newPowerPlant(toPowerPlantRow(success)).recover {
          case NonFatal(ex) =>
            Future.successful { UnprocessableEntity(
              Json.obj("message" -> s"Could not create new PowerPlant because of ${ex.getMessage}")
            ) }
        }
        Future.successful { Ok("") }
      }
    )
  }
这就是我认为的原因:

Controller.scala:103: a type was inferred to be `Any`; this may indicate a programming error.
[error]       success => {
[error]                  ^
[error] one error found
[error] (compile:compileIncremental) Compilation failed
[error] Total time: 16 s, completed Aug 21, 2017 9:46:30 AM
你知道为什么会发生这种错误吗?我确信这与编译器有关,因为我的控制器中有类似的代码,可以编译

build.sbt中有
“-Xfatal警告”
。这使得编译器抛出一个编译错误,而在常规情况下,它只是一个警告。 为了检查这一点,我对
“-Xfatal警告”
进行了注释。然后
sbt clean compile
给出:

alex@POSITRON /ssd2/projects/PowerPlantProblem/plant-simulator $ sbt clean compile
[info] Loading project definition from /ssd2/projects/PowerPlantProblem/plant-simulator/project
[info] Updating {file:/ssd2/projects/PowerPlantProblem/plant-simulator/project/}plant-simulator-build...
Waiting for lock on /home/alex/.ivy2/.sbt.ivy.lock to be available...
[info] Resolving org.fusesource.jansi#jansi;1.4 ...
[info] Done updating.
[info] Set current project to plant-simulator (in build file:/ssd2/projects/PowerPlantProblem/plant-simulator/)
[success] Total time: 0 s, completed Aug 21, 2017 3:39:57 PM
[info] Updating {file:/ssd2/projects/PowerPlantProblem/plant-simulator/}root...
[info] Resolving jline#jline;2.14.3 ...
[info] Done updating.
[info] Compiling 31 Scala sources and 2 Java sources to /ssd2/projects/PowerPlantProblem/plant-simulator/target/scala-2.11/classes...
[warn] /ssd2/projects/PowerPlantProblem/plant-simulator/app/com/inland24/plantsim/controllers/PowerPlantController.scala:102: a type was inferred to be `Any`; this may indicate a programming error.
[warn]           case Some(row) => dbService.newPowerPlant(row) recoverWith{
[warn]                ^
[warn] one warning found
[success] Total time: 23 s, completed Aug 21, 2017 3:40:20 PM
alex@POSITRON /ssd2/projects/PowerPlantProblem/plant-simulator $ 
这意味着我的建议是正确的。 因此,您要么禁用该
“-Xfatal warnings”
,要么使代码满足它带来的更严格的要求

现在,为了了解警告本身,请查看
recoverWith
方法的签名:

def recoverWith[U>:T](pf:PartialFunction[Throwable,Future[U]](隐式执行器:ExecutionContext):Future[U]

在您的情况下,
T
Int
。所以
Int
Future[Result]
的任何共同祖先当然是
any
。 只需插入如下所示的
Int
值,即可使用
“-Xfatal warnings”
对其进行编译:

case Some(row) => dbService.newPowerPlant(row) recoverWith{
  case ex: Exception => Future.successful{
    UnprocessableEntity(
      Json.obj("message" -> s"Could not create new PowerPlant because of ${ex.getMessage}")
    )
    5
  }
}
这里的警告很有意义,因为代码不干净:您正试图通过返回
UnprocessableEntity
HTTP状态来恢复向DB插入行的问题(例如,DB服务器关闭),该状态实际上没有任何意义,考虑到您在这之后通过
Future.successful{Ok(“”)}覆盖了此意图

希望这能有所帮助。

有来自

为了解决这个问题,我做了以下工作:

def createNewPowerPlant = Action.async(parse.tolerantJson) { request =>
    request.body.validate[PowerPlantConfig].fold(
      errors => {
        Future.successful(
          BadRequest(Json.obj("message" -> s"invalid PowerPlantConfig $errors"))
        )
      },
      success => {
        toPowerPlantRow(success) match {
          case None => Future.successful(
            BadRequest(Json.obj("message" -> s"invalid PowerPlantConfig ")) // TODO: fix errors
          )
          case Some(row) =>
            dbService.newPowerPlant(row).materialize.map {
              case Success(insertedRecordId) =>
                Ok("TODO: Send a Success JSON back with the id of the newly inserted record")
              case Failure(ex) =>
                UnprocessableEntity(
                  Json.obj("message" -> s"Could not create new PowerPlant because of ${ex.getMessage}")
                )
            }
        }
      }
    )
  }

注意,我正在使用Monix库中的MaterializeFutureExtensions方法

如果我删除恢复代码blcok,我可以通过编译器!这是为什么?您是否尝试过在
案例非致命(ex)=>Future之后立即用括号
()
替换大括号
{}
。成功了
?是的,我尝试过!但这不是问题所在!编译程序看到这段代码的方式存在根本性的错误!您可以在这里找到完整的源代码:我怀疑build.sbt中的linter导致了这个问题!我已经更新了答案。因此,我克隆了存储库,它在我的笔记本电脑上编译得很好。很难说为什么会出现编译器错误。如果您在本地拥有相同的build.sbt,那么就非常奇怪了。我在Linux上运行,有Java8.Hmm。。这太奇怪了!天哪,你已经对代码的这一部分进行了注释,我现在看到了。检查。