Scala的getter / setter问题

时间:2011-07-07 01:06:59

标签: scala

我目前正在学习Scala,并且刚刚发现了创建自定义字段getter / setter的方法。我有一个简单的例子:

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

在控制台上,我可以这样做:

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

现在我试图将这个概念带到一个稍微复杂的例子;我会尝试将代码简化为相关内容:

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)}
}

据我所知,我已经做了我需要做的事情,以便能够通过其吸气剂和制定者将value作为一个领域进行处理。但是当我在控制台中尝试时,我得到了:

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
               ^

我做错了什么,我该如何解决?

2 个答案:

答案 0 :(得分:11)

我实际上偶然发现了解决方案。

我声明我的值函数的行:def value() = cachedValue是罪魁祸首。 如果我删除括号以使行def value = cachedValue一切似乎都按预期工作。

答案 1 :(得分:-1)

您无法更改Scala中的值。值只分配一次且仅分配一次。如果你想这样做,那么你需要使用变量而不是值。换句话说,将声明从val更改为var

问题出在你的一个类定义中,并且可能在没有val的行上,因为我相信如果你忽略声明一个名字,那么Scala会认为它是一个值,因此是不可变的。

虽然不确定你想要什么吸气剂和制定者。 Scala使您可以忽略所有Java开销。

可能是cachedValue = initialValue这一行,因为它没有在该类的任何地方用var声明。另一个类中的定义是一个不同的名称,因为它在不同的范围内。你不得不说类似于class.varname来改变另一个类中定义的变量。