0

我有一个 Scala def,它从 HTTP POST 获取参数并解析数据。我正在从数据库中提取一个“作业”对象(在调试器中验证查询成功,并且参数与它们需要的一样)并且我正在尝试使用新参数更新该作业对象。但是,尝试分配值被证明是无用的,因为作业对象保留了所有原始值。

所有数据库对象都来自 Squeryl。下面的代码:

编辑:在下面添加了类和 Job 对象以帮助在此 Play 中提供上下文!应用程序

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然后我得到一个 Scalareassignment to val错误。尝试var name而不是val name.

这显然是我的语法问题,处理这个问题的正确方法是什么?谢谢!

更多信息:如果这有帮助,这里是我们 Play 中使用的 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] {
}
4

2 回答 2

3

job.name是一个不可变的属性,所以你不能用job.name = name. 您可以在用声明的Job类的定义中看到,这意味着它的值是不可变的并且永远无法更改。“更改”对象值的唯一方法是实际创建一个全新的实例并丢弃旧实例。这是处理不可变对象时的标准做法。namevaljob

name将本地从更改valvar无关紧要,因为您只是在读取该变量的值。

于 2012-02-13T20:33:04.287 回答
0

val是不可变的,在 fat 中,整个Job类都是不可变的(因为所有字段都是)。

可以做的是创建一个案例类JobW和一些拉皮条以允许使用 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"))

我所做的是将(为练习简化)作业包装到案例类包装器中,并定义隐式转换。

使用这种隐式转换(所谓的拉皮条),您将可以访问该ok方法,也可以访问该方法copy

copy方法是在案例类上注入的方法,它接受与案例类一样多的参数作为字段,并生成案例类的新实例。

因此,您现在只能更改类的一个值,我的意思很简单,并检索一个新对象(作为函数式编程的不变性)。

于 2012-02-13T21:10:12.363 回答