我有一个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] {
}
答案 0 :(得分:3)
job.name
是一个不可变属性,因此您无法使用job.name = name
更改其值。您可以在Job
类的定义中看到name
声明为val
,这意味着它的值是不可变的,永远不能更改。 “更改”job
对象的值的唯一方法是实际创建一个全新的实例并丢弃旧的实例。这是处理不可变对象时的标准做法。
将您的本地name
从val
更改为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类的新实例。
所以你现在能够只更改你的类的一个值,非常简单的意思是,并检索一个新的对象(因为函数编程是不可变的)。