Why can't I assign to var in Scala subclass?

后端 未结 2 885
独厮守ぢ
独厮守ぢ 2021-02-07 10:37

Suppose I have the following abstract class:

abstract class A (var is_happy : Boolean) {
  def toggle_happiness();
}

And now I want to define a

相关标签:
2条回答
  • 2021-02-07 11:17

    There is another simple solution. One that only requires to modify B (no need to change the base class) and won't modify the interface (no parameter renaming). Just introduce a private method that returns this, and explicitly dereference this:

    class B (var is_happy : Boolean) extends A {
      private def self = this
      def toggle_happiness() = {
        self.is_happy = !self.is_happy
      }
    }
    

    Note that this work around is localized to B. Everywhere else (included in derived classes) you can keep using just is_happy (no need for self.is_happy).


    As a side note, we should really be able to directly dereference this, as in this.is_happy (instead of adding the self method and doing self.is_happy). But for some reason the compiler will blindly treat this.is_happy the same as is_happy, so we get back to square one and this.is_happy actually still point to B's parameter rather than A's variable. This very much looks like a compiler bug to me.

    0 讨论(0)
  • 2021-02-07 11:32

    See this question. Essentially, Scala thinks that you're trying to assign to the constructor parameter, is_happy, rather than the var, is_happy, which just happens to have the same name. Some solutions are to:

    • Make the var abstract in the base class.
    • Rename the constructor parameter (e.g. _is_happy). Since parameter names are part of the public API of your constructors/methods, this may not be advisable.

    You're fortunate that the problem was detected at compile time in your case. This issue can lead to very surprising runtime behavior when it goes undetected.

    0 讨论(0)
提交回复
热议问题