Я совершенно новый, чтобы поднять. Моя цель - сделать небольшое приложение, которое позволит мне ввести данные о научных статьях (исследованиях) в базу данных.Какова продолжительность жизни объекта при использовании лифта?
Я еще не собираюсь создавать базу данных, все еще играя с получением формы ввода для работы. Поэтому я решил, что проведу несколько исследований в памяти, в списке сопутствующего объекта для класса Study. Я также создал переменную аккумулятора для выдачи уникальных идентификаторов, если у меня нет СУБД, управляющей идентификаторами.
В качестве теста на дым я посетил страницу, на которой был показан список исследований (засеянных двумя исследованиями в коде), затем посетил страницу формы, вошел в новое исследование и снова перешел к списку исследований. Я был удивлен, увидев, что мое новое исследование имеет идентификатор 1 вместо 3, поэтому в какой-то момент моя переменная аккумулятора должна быть сброшена. Но исследования по сбору ListBuffer не были сброшены, поскольку он показал все три исследования. Добавление большего количества результатов исследований приводит к тому, что счетчик увеличивается на 1 каждый раз.
Литература, которую я нашел на лифте (две бесплатные книги по Liftweb, а также сборник Cookie Cookie от 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)
}
}
Вот представление трех исследований:
обновление Мое понимание того, что происходит (может быть, конечно, неверно):
Я открываю страницу, показывающую список исследований. Это вызывает
allStudies
.studiesList
инициализируется, чтобы содержать Brooks1975 и Dijkstra1968. Во время построения исследований currentId инициализируется до 0, а затем увеличивается на 2.Открываю форму заявки и добавляю третье исследование.
addStudy
извлекаетallStudies
из памяти, не инициализируя его снова. Он инициализирует currentId до 0. Я закончил третье исследование с ID 1.Я показываю все исследования, а затем возвращаюсь на страницу формы входа. На этот раз
addStudy
извлекает из памяти какallStudies
, так иcurrentId
. Я получаю четвертое исследование с идентификатором 2.
В комментариях указано, что это, вероятно, Scala-специфическое и не связанное с Lift. Но все же я не понимаю, почему currentId
инициализируется два раза (в шагах 1 и 2), а не один раз (как только сам объект создается) или каждый раз, когда он читается. Я бы ожидал первого поведения, но даже повторная инициализация каждый раз кажется более логичной, чем случайная повторная инициализация только один раз.
Не проблема, что ваш currentId имеет значение 0, прежде чем вы вызовете addStudy, даже если вы уже заселили 2 исследования в свой кабинетList? Вероятно, вы должны инициализировать currentId для изученияList.length, а не 0? –
@ EthanJewett это именно то, что я прошу. Почему currentId повторно инициализируется при повторном запросе страницы, но studyList не повторно инициализируется для seedStudies.to [ListBuffer]? Когда я могу ожидать повторной инициализации и повторной инициализации? – rumtscho
Что @EthanJewett говорит, что ошибка не имеет ничего общего с лифтом, это порядок инициализации Scala. Вы определяете список, затем следующим шагом в инициализации является сброс currentId обратно на 0. Если вы переместите строку 'priveate var currentId = 0' в начало вашего объекта-компаньона (над декларацией' seedStudies'), она должна работайте, как ожидалось. – jcern