开发者

Problem with Scala's getter/setters

I'm currently learning Scala, and just discovered the way to create custom field getters/setters. I have a simple example working:

class Thing(private val a:Int){
  override def toString = "Thing[" + a + "]"
  private var开发者_JS百科 _value = a
  def value = _value
  def value_= (newVal:Int) = _value = newVal
}

On the console I can do:

scala> var t = new Thing(2)
t: dylan.code.Thing = Thing[2]

scala> t.value
res1: Int = 2

scala> t.value = 3

scala> t.value
res2: Int = 3

Now I'm trying to bring this concept to a slightly more complicated example; I'll try to whittle the code down to what's relevant:

abstract class CellExpression[Type] extends Publisher[CellUpdateEvent[Type]] with Subscriber[CellUpdateEvent[Type], CellExpression[Type]]{
    protected var cachedValue: Type = recalculateValue() 
    protected def recalculateValue(): Type

    protected def changeValue(newValue: Type):Unit = {
        val oldValue = value()
        if(newValue != oldValue){
            cachedValue = newValue
            publish(new CellUpdateEvent(this, oldValue, newValue))
        }
    }

    def value() = cachedValue
    def notify(pub: CellExpression[Type], event: CellUpdateEvent[Type]) = changeValue(recalculateValue())
}
//....
class CellVariable[Type](private val initialValue:Type) extends CellExpression[Type]{
    cachedValue = initialValue
    protected def recalculateValue() = { cachedValue }
    override def toString = "CellVariable[" + value + "]"
    def value_= (newValue:Type) = {changeValue(newValue)}
}

As far as I can tell, I've done what I need to in order to be able to treate value as a field via its getter and setter. But when I try it out in the console, I get:

scala> var i = new CellVariable(2)
i: dylan.code.CellVariable[Int] = CellVariable[2]

scala> i.value = 3
<console>:11: error: reassignment to val
       i.value = 3
               ^

What have I done wrong, and how can I fix it?


I actually stumbled onto the solution.

The line where I declare my value function: def value() = cachedValue is the culprit. If I remove the parentheses to make the line def value = cachedValue everything seems to work as I expected.


You cannot change values in Scala. A value is assigned once and only once. If you want to do this then you need to use variables instead of values. In other words, change the declaration from val to var.

The problem is inside one of your class definitions and may be on a line without val because I believe that if you neglect to declare a name, then Scala assumes that it is a value and therefore immutable.

Not sure what you want getters and setters for though. Scala enables you to ignore all of that Java overhead.

It is probably the line that says cachedValue = initialValue because it is not declared with var anywhere in that class. The definition in the other class is a different name because it is in a different scope. You would have to say something like class.varname to change a variable defined in another class.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜