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。。这太奇怪了!天哪,你已经对代码的这一部分进行了注释,我现在看到了。检查。