Как правильно установить значение объекта в Scala? - PullRequest
0 голосов
/ 14 февраля 2012

У меня есть определение Scala, которое берет параметры из HTTP POST и анализирует данные. Я извлекаю объект «задание» из базы данных (запрос был успешным, что подтверждено в отладчике, и параметры соответствуют требованиям), и я пытаюсь обновить этот объект задания новыми параметрами. Однако попытки присвоить значения оказываются бесполезными, поскольку объект задания сохраняет все исходные значения.

Все объекты базы данных от Squeryl. Код ниже:

Редактировать: добавлен класс ниже и объект задания, чтобы помочь создать контекст в этой игре! Приложение

object Job {
  def updateFromParams(params:Params) = {
    val job = Job.get( params.get("job_id").toLong ).get

    val comments =  params.get("comments")
    val startTime = parseDateTime(params.get("start_time") + " " + params.get("date"))
    val endTime = parseDateTime(params.get("end_time") + " " + params.get("date"))
    val clientId = params.get("client_id").toLong
          val client = Client.get(clientId).get
    val name = params.get("job_name")
    val startAddressType = params.get("start_address_type")
    var startLocationId:Option[Long] = None
    val (startAddress, startCity, startProvince) = startAddressType match {
      case "client" => getClientAddress(clientId)
      case "custom" => (params.get("start_custom_address"),
                params.get("start_custom_city"),
                params.get("start_custom_province"))
      case id => {
      startLocationId = Some(id.toLong)
        getLocationAddress(startLocationId.get)
      }
    }

    job.comments ->  comments
    job.startTime -> startTime
    job.endTime -> endTime
    job.clientId -> clientId
    job.name -> name
    job.startAddressType -> startAddressType
    job.startAddress -> startAddress
    job.startCity -> startCity
    job.startProvince -> startProvince


    Job.update(job)
  }
}

Я в тупике, потому что если я пытаюсь job.name -> name ничего не происходит, а если я пытаюсь job.name = name, то я получаю ошибку Scala reassignment to val. Я получаю ту же ошибку при попытке var name вместо val name.

Это, очевидно, проблема с синтаксисом с моей стороны, какой правильный способ справиться с этим? Спасибо!

Дополнительная информация: Если это поможет, вот класс Job, используемый в нашей игре! Приложение:

class Job(
  val id: Long,

  @Column("name")
  val name: String,

  @Column("end_time")
  val endTime: Timestamp,

  @Column("start_time")
  val startTime: Timestamp,

  @Column("client_id")
  val clientId: Long,

  @Column("start_address_type")
  var startAddressType:String,

  @Column("start_address")
  var startAddress: String,
  /* LOTS MORE LIKE THIS */
) extends KeyedEntity[Long] {
}

Ответы [ 2 ]

3 голосов
/ 14 февраля 2012

job.name является неизменным свойством, поэтому вы не можете изменить его значение с помощью job.name = name. В определении класса Job вы можете видеть, что name объявлен с val, что означает, что его значение является неизменным и никогда не может быть изменено. Единственный способ «изменить» значения объекта job - это создать абсолютно новый экземпляр и отказаться от старого. Это стандартная практика при работе с неизменными объектами.

Изменение локального name с val на var не будет иметь значения, поскольку вы только читаете значение этой переменной.

0 голосов
/ 14 февраля 2012

val являются неизменяемыми, в жирном случае весь класс Job является неизменным (так как все поля являются).

Что можно сделать, это создать класс наблюдений JobW и немного pimpingразрешить использование copy.Тем не менее:

class Job(val id:Long, val name:String) {}

case class JobW(override val id:Long, override val name:String) extends Job(id, name){
  def ok:String = name + id
}

implicit def wrapJob(job:Job):JobW = JobW(job.id, job.name)

val job:Job = new Job(2L, "blah")

println(job.ok)

println(job.copy(name="Blob"))

То, что я сделал, - это завершение задания (упрощенного для упражнения) в оболочку класса case и определение неявного преобразования.

Использование этого неявногопреобразование (так называемое сутенеринг), у вас будет доступ к методу ok, но также и к методу copy.

Метод copy является внедренным в case-классах, который занимает столько жеаргументы в качестве класса case как поля и создают новый экземпляр класса case.

Таким образом, теперь у вас есть возможность изменить только одно значение вашего класса, я имею в виду очень просто, и получить новый объект (какфункциональное программирование требует неизменности).

...