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

What is the lifetime of an object when using Lift?

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

我还没有着手制作数据库,仍在尝试让报名表发挥作用。所以我决定我将在内存中保存一些研究,在研究的伴随对象列表中 class。我还创建了一个累加器变量来分配唯一 ID,只要我没有管理 ID 的 DBMS。

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

我找到的关于 Lift 的文献(Liftweb 上的两本免费书籍,以及 Gilberto Garcia 的 Lift Application Development Cookbook)是不完整的,更像是一个迷你教程的集合,他们没有解释 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)
  }
}

以下是三项研究的代表:

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

  1. 我打开显示研究列表的页面。这调用 allStudiesstudiesList 初始化为包含 Brooks1975 和 Dijkstra1968。建房时,currentId初始化为0,然后自增2。

  2. 我打开报名表并添加第三个学习。 addStudy 从内存中检索 allStudies,无需再次初始化。它将 currentId 初始化为 0。我最终得到了 ID 为 1 的第三项研究。

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

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

进入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 所建议的那样。一般来说,我会说将所有声明放在 类 或对象的顶部,并始终在使用变量之前声明,而不是相反。