如何在Scala中正确设置对象的值?

时间:2012-02-13 20:16:26

标签: scala squeryl

我有一个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,那么我会收到Scala reassignment 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] {
}

2 个答案:

答案 0 :(得分:3)

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

将您的本地nameval更改为var无关紧要,因为您只是在阅读该变量的值。

答案 1 :(得分:0)

val是不可变的,胖子整个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"))

我所做的是将(练习的spimplified)Job包装到case类包装器中,并定义隐式转换。

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

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

所以你现在能够只更改你的类的一个值,非常简单的意思是,并检索一个新的对象(因为函数编程是不可变的)。