1

我已经测试了相同代码的三个变体,我让它工作得很好。我想知道为什么会有不同的行为。

所以我有这个工作代码,它将长时间戳转换为 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 framework 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 */ }
   }
  }
}

这是您的基本游戏框架异步操作调用。

4

1 回答 1

2

由于第 1 个和第 3 个示例之间的区别是lazy val,因此我会查看您的调用 ( ) 的确切位置100000L.asECMADateStringlazy val有助于纠正一些混入的“初始化顺序”问题,例如:查看这个最近的问题,看看它是否与你的相似。

于 2013-05-20T15:11:48.137 回答