我找到了以下代码,但不确定如何运行。这是带有Play框架的Scala代码。
## route file ##
GET /:object @controllers.ResultsController.resultController(object)
## ResultsController file ##
def resultController(object: SomeObject) = {
getResult(object)
}
def private getResult(object: SomeObject): Result = {
lazy val result = computeResult(object) match {
case Some(response) => JsonOk(response)
case None => JsonInternalError(...)
}
result
}
我不确定何时评估result
。
我的意思是,退货是在使用时必须评估的东西,还是在退货时解决?
懒惰的特性离开了函数的上下文?
在这种情况下,从不使用该值,而仅作为GET请求的结果返回。
非常感谢!
答案 0 :(得分:6)
是的,懒惰的result
在getResult
内部求值并返回。 Result
-getResult
的返回类型不是惰性的,实际上您不能将函数的返回类型定义为惰性的。如果出于某种原因您确实需要这种计算是惰性的,则可能应该像() => Result
或Future[Result]
这样。
同样的想法“ 在这种情况下,从不使用该值,仅作为GET请求的结果返回。”显然是错误的。浏览器不了解Scala,它了解HTTP(一种文本格式)。这意味着框架必须将Result
转换为文本形式(即序列化),并且无论如何肯定需要对其进行评估。
答案 1 :(得分:1)
我在自然的解释中添加了行号。
1 def private getResult(object: SomeObject): Result = {
2 lazy val result = computeResult(object) match {
3 case Some(response) => JsonOk(response)
4 case None => JsonInternalError(...)
5 }
6 result
7 }
6
上解析。因此它从方法getResult
lazy
使用synchronized
锁定在里面。 lazy
始终验证变量是否已解析。 result
变量是局部变量,始终使用且仅使用一次。因此,lazy
毫无意义。 在您的示例中,根据点“ 2”和“ 3”,lazy
会降低程序速度。它还可能导致行2
,3
,4
上的潜在死锁。有关更多数据,请参见本文https://blog.codecentric.de/en/2016/02/lazy-vals-scala-look-hood/中的“方案3:与同步结合使用的死锁”。
我的建议是在此处删除lazy
。