我已经测试了相同代码的三种变体,我让它工作得很好。我想知道为什么会有不同的行为。
所以我有这个工作代码,它将长时间戳转换为ECMA日期标准格式的字符串:
lazy val dateFormat = new java.text.SimpleDateFormat("yyyy-MM-DD'T'HH:mm:ss.sssZ")
implicit def dateToECMAFormat(time: Long) = new {
def asECMADateString: String = {
dateFormat.format(new java.util.Date(time))
}
}
其他有效的变体:
implicit def dateToECMAFormat(time: Long) = new {
val dateFormat = new java.text.SimpleDateFormat("yyyy-MM-DD'T'HH:mm:ss.sssZ")
def asECMADateString: String = {
dateFormat.format(new java.util.Date(time))
}
}
但我不希望SimpleDateFormat一直重新安装。所以我优先考虑第一个。但现在真正的谜团:
val dateFormat = new java.text.SimpleDateFormat("yyyy-MM-DD'T'HH:mm:ss.sssZ")
implicit def dateToECMAFormat(time: Long) = new {
def asECMADateString: String = {
dateFormat.format(new java.util.Date(time))
}
}
最后一段代码编译但在运行时抛出异常;我没有设法从play框架获取堆栈跟踪。我只知道我的控制器在播放框架2.1中返回500(内部服务器错误)而没有任何更多信息(其他控制器工作但主要服务仍在运行)。
在每种情况下,通话都是这样的:100000L.asECMADateString
有人可以向我解释不同的行为,为什么最后一行不起作用?虽然我很好地理解了val,lazy val和def之间的区别,但现在我觉得我错过了一些东西。
代码在这样的对象中调用:
object MyController extends Controller{
implicit val myExecutionContext = getMyExecutionContext
lazy val dateFormat = new java.text.SimpleDateFormat("yyyy-MM-DD'T'HH:mm:ss.sssZ")
implicit def dateToECMAFormat(time: Long) = new {
def asECMADateString: String = {
dateFormat.format(new java.util.Date(time))
}
}
def myAction = Action {
Async {
future {
blocking{
//here get some result from a db
val result = getStuffFromDb
result.someLong.asECMADateString
}
} map { result => Ok(result) } recover { /* return some error code */ }
}
}
}
这是您的基本playframework异步动作调用。
答案 0 :(得分:2)
由于第1个和第3个示例之间的差异是lazy val
,因此我正在查看 您的呼叫(100000L.asECMADateString
)的确切位置。 lazy val
有助于纠正混合内容的某些“初始化顺序”问题,例如:请参阅this recent issue以查看它是否与您的相似。