2015-02-12 2 views
0

Я совершенно новый, чтобы поднять. Моя цель - сделать небольшое приложение, которое позволит мне ввести данные о научных статьях (исследованиях) в базу данных.Какова продолжительность жизни объекта при использовании лифта?

Я еще не собираюсь создавать базу данных, все еще играя с получением формы ввода для работы. Поэтому я решил, что проведу несколько исследований в памяти, в списке сопутствующего объекта для класса 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) 
    } 
} 

Вот представление трех исследований:

The output of the above

обновление Мое понимание того, что происходит (может быть, конечно, неверно):

  1. Я открываю страницу, показывающую список исследований. Это вызывает allStudies. studiesList инициализируется, чтобы содержать Brooks1975 и Dijkstra1968. Во время построения исследований currentId инициализируется до 0, а затем увеличивается на 2.

  2. Открываю форму заявки и добавляю третье исследование. addStudy извлекает allStudies из памяти, не инициализируя его снова. Он инициализирует currentId до 0. Я закончил третье исследование с ID 1.

  3. Я показываю все исследования, а затем возвращаюсь на страницу формы входа. На этот раз addStudy извлекает из памяти как allStudies, так и currentId. Я получаю четвертое исследование с идентификатором 2.

В комментариях указано, что это, вероятно, Scala-специфическое и не связанное с Lift. Но все же я не понимаю, почему currentId инициализируется два раза (в шагах 1 и 2), а не один раз (как только сам объект создается) или каждый раз, когда он читается. Я бы ожидал первого поведения, но даже повторная инициализация каждый раз кажется более логичной, чем случайная повторная инициализация только один раз.

+1

Не проблема, что ваш currentId имеет значение 0, прежде чем вы вызовете addStudy, даже если вы уже заселили 2 исследования в свой кабинетList? Вероятно, вы должны инициализировать currentId для изученияList.length, а не 0? –

+0

@ EthanJewett это именно то, что я прошу. Почему currentId повторно инициализируется при повторном запросе страницы, но studyList не повторно инициализируется для seedStudies.to [ListBuffer]? Когда я могу ожидать повторной инициализации и повторной инициализации? – rumtscho

+1

Что @EthanJewett говорит, что ошибка не имеет ничего общего с лифтом, это порядок инициализации Scala. Вы определяете список, затем следующим шагом в инициализации является сброс currentId обратно на 0. Если вы переместите строку 'priveate var currentId = 0' в начало вашего объекта-компаньона (над декларацией' seedStudies'), она должна работайте, как ожидалось. – jcern

ответ

3

Перейти в лестницу РЕПЛ, войти в режим вставки (: клейстер) команду, и поставить в следующем:

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. В общем, я бы сказал, чтобы все ваши объявления находились в верхней части ваших классов или объектов и всегда объявляли перед использованием переменной, а не наоборот.

+0

Эти вопросы могут дать немного больше информации о порядке инициализации: http://stackoverflow.com/questions/12184997/scala-and-forward-references/12185918#12185918 и http://stackoverflow.com/questions/7762838/ форвардные ссылки, почему-делает-это-код-компиляции – jcern

Смежные вопросы