使用Lift时对象的生命周期是多少?

时间:2015-02-12 14:37:16

标签: scala lift lifecycle

我对Lift完全不熟悉。我的目标是制作一个小应用程序,让我将有关科学文章(研究)的数据输入数据库。

我还没有建立数据库,还在玩一个输入表格。所以我决定在记忆中进行一些研究,在研究班的伴随对象列表中。我还创建了一个累加器变量来分配唯一的ID,只要我没有管理ID的DBMS。

作为烟雾测试,我访问了显示研究列表的页面(在代码中进行了两项研究),然后访问了表单页面,进入了一项新研究,并再次导航到研究列表。我很惊讶地看到我的新研究的ID为1而不是3,因此在某些时候,我的累加器变量必须已经重置。但ListBuffer收集研究没有重置,因为它显示了所有三项研究。添加更多研究会导致计数器每次递增1。

我在Lift上找到的文献(两本关于Liftweb的免费书籍,以及Gilberto Garcia的升级应用程序开发指南)都不完整,更像是一系列迷你教程,但它们没有解释Lift的工作原理。

那么我的Study对象的实际生命周期是什么,以及为什么一个可变变量在重新打开页面后重置而不是另一个?

package org.rumtscho.litsuche
package study

import scala.collection.mutable.ListBuffer

class Study private[study](
    val id: Int,
    val handmadeAuthorRef: String,  
    val humanReadableDescription: String ) 
{
}

object Study {
  val seedStudies = List(
          new Study(dispenseNextFreeId, "Brooks1975", "Tells us that throwing more programmers at a project makes it run late, not early"), 
          new Study(dispenseNextFreeId, "Dijkstra1968", "Recognizes that we need structured code")
      )

   private var studiesList = seedStudies.to[ListBuffer]
   private var currentId = 0


   private def dispenseNextFreeId: Int = {
    currentId = currentId + 1
    return currentId
  }

   def allStudies = studiesList.toList

   def addStudy(reference: String, description: String): Unit = {
     studiesList += new Study(dispenseNextFreeId, reference, description)
  }
}

这是三项研究的代表:

The output of the above

更新我对正在发生的事情的理解(当然可能是错的):

  1. 我打开显示研究列表的页面。这会调用allStudiesstudiesList初始化为包含Brooks1975和Dijkstra1968。在构建研究期间,currentId初始化为0,然后增加到2.

  2. 我打开报名表并添加第三项研究。 addStudy从内存中检索allStudies,而不是再次初始化它。它将currentId初始化为0.我最终进行了第三项ID为1的研究。

  3. 我显示所有研究,然后返回报名表页面。这一次,addStudy从内存中检索allStudiescurrentId。我得到第四项ID为2的研究。

  4. 评论指出,这可能是Scala特有的,与Lift无关。但是,我仍然不明白为什么currentId被初始化两次(在步骤1和2中),而不是一次(一旦创建对象本身)或每次被读取。我本来期望第一种行为,但即使每次重新初始化似乎都比仅随机重新初始化更合乎逻辑。

1 个答案:

答案 0 :(得分:3)

进入scala REPL,进入粘贴模式(:paste)命令,并输入以下内容:

def increment {
  currentId = currentId + 1
}

increment
increment

var currentId = 0

然后尝试

var currentId = 0

def increment {
  currentId = currentId + 1
}

increment
increment

在第一个例子中,currentId以值0结束。在第二个例子中,它以值2结束。为什么会发生这种情况?我不是Scala声明方面的专家,但看起来这就是你遇到的同样问题。

似乎解决方案正如@jcern所暗示的那样。一般来说,我会说你的所有声明都放在你的类或对象的顶部,并且在使用变量之前总是声明,而不是相反。