我发现自己遇到了容易出错的代码;模式是这样的:
final class StateVars(val x:Int, val y:Int)
final class StateVarsMutable(var x:Int, var y:Int) {
// req. case classes & >1 element w/ same ordering
// - can also do similar with shapeless
// def snapshot():StateVars = StateVars.tupled(
// StateVarsMutable.unapply(this).get )
def snapshot() = new StateVars(x, y) // generic
}
在上面的实例中,StateVarsMutable可能包含在Actor中,但是Actor有时可能会通过StateVars发送其状态的快照。似乎可以使用kailuowang's henkan。在不影响运行时性能的情况下,是否存在针对这种情况的最佳或通用方法?
答案 0 :(得分:0)
不可变类的可变性
问题中描述的模式是不必要的。
case class
in scala通过使用persistent data structure模式解决了该问题试图解决的问题。
修改问题的类声明以包含“ case”:
final case class StateVars(x: Int, y: Int)
现在可以通过返回代表新状态的新对象来“突变”此状态:
val initialState = StateVars(0,0)
//Increment x while keeping y the same
val incrementX : StateVars = initialState copy (x = initialState.x + 1)
//Increment y while keeping x the same
val incrementY : StateVars = initialState copy (y = initialState.y + 1)
如果您需要持续维护“快照”,请使用var
:
var snapshot : StateVars = StateVars(0,0)
snapshot = snapshot copy (x = snapshot.x + 1, y = snapshot.y +1)
演员内部
可以使用Actor
编写一个var
来维护“快照”,以允许更改值:
object StateVarsRequest
class StateVarsActor(initialStateVars : StateVars) extends Actor {
private var snapshot : StateVars = initialStateVars
override def receive : Receive = {
case stateVars : StateVars => snapshot = stateVars
case _ : StateVarsRequest => sender ! snapshot
}
}
snapshot
可以看作是指向不可变类的指针。当请求者在消息中收到快照时,他们不是在获取可变指针,而是在获取不可变数据。
因此,如果快照在请求者收到其数据后发生更改,则该请求者的数据不会更改。