Неожиданная ошибка: переназначение в val

Я получаю эту ошибку при компиляции:

Compilation error: reassignment to val

Я думаю, что это кажется очевидным, но, глядя на мой код, я не могу понять, почему это не работает.

Вот пример кода, где происходит ошибка, из моего ConferenceController.scala:

def createConfWithPrivacy(confId: Long, groupId: Option[Long]) = ForcedAuthentication 
{implicit request =>
    Future {
      val user = request.user.get
      var newConf = Conference.findById(confId).get
      if(groupId.isDefined){
        newConf.forGroup = LabGroup.findById(groupId.get)  <- there it is
        Conference.updateForGroup(newConf)
      }
      ...
    }
}

Переменные в Conference.scala объявлены следующим образом:

case class Conference (
    id         : Long,
    title      : String,
    abstr      : String,
    speaker    : Speaker,
    startDate  : DateTime,
    length     : Duration,
    organizedBy: Lab,
    location   : Location,
    accepted   : Boolean,
    acceptCode : Option[String],
    priv       : Boolean,
    forGroup   : Option[LabGroup]=None
) {... Functions ...}

Вызванные функции взяты из файла LabGroup.scala, я знаю, что эта работает:

def findById(id: Long): Option[LabGroup] = DB.withConnection { implicit  c =>
    SQL("SELECT * FROM LabGroup WHERE id = {id}")
      .on("id" -> id)
      .as(labGroupParser.singleOpt)
  }

Но я не понимаю, почему эта ошибка происходит, потому что newConf - это переменная, и обычно Conference.forGroup тоже должна быть такой.

Если вы видите, что что-то сделано не так, пожалуйста, сообщите мне.

Спасибо за помощь.

2 ответа

Решение

Когда вы создаете экземпляр класса case, как вы это сделали, каждый его член по умолчанию является val. Вы должны явно указать Scala, что хотите использовать его как var. Просто сделай это так:

case class Conference (
    id         : Long,
    ...
    var forGroup   : Option[LabGroup]=None
)

РЕДАКТИРОВАТЬ:
Как написал в своем комментарии Régis Jean-Gilles, более идиотским способом изменения значения forGroup будет следующий код:

newConf.forGroup = newConf.copy (forGroup = LabGroup.findById (groupId.get))

Это оставит forGroup в качестве значения и станет лучшим [функциональным] способом "переназначения".

var newConf = Conference.findById(confId).get определяет переменную newConf, Эта переменная может быть переназначена. Тем не менее forGroup значение newConf это все еще только значение, и как таковое оно не может быть изменено.

Если вы хотите обновить forGroup за newConfЗатем необходимо объявить переменную, которую вы можете сделать с помощью:

case class Conference (
    id         : Long,
    // ...
    var forGroup   : Option[LabGroup]=None
)
Другие вопросы по тегам