开发者

Scala: can't write setter without getter?

This works:

class ButtonCountObserver 开发者_高级运维{
  private var cnt = 0  // private field
  def count = cnt      // reader method
  def count_=(newCount: Int) = cnt = newCount  // writer method
 // ...
}

val b = new ButtonCountObserver 
b.count = 0

But this doesn't

class ButtonCountObserver {
  private var cnt = 0  // private field
  def count_=(newCount: Int) = cnt = newCount  // writer method
 // ...
}

val b = new ButtonCountObserver 
b.count = 0

I get: error: value count is not a member of ButtonCountObserver

Is it possible to create a setter (with the syntactic sugar) without a getter?


The spec requires that both a setter and getter are defined to be able to use the syntactic sugar for calling the setter:

The interpretation of an assignment to a simple variable x = e depends on the definition of x. If x denotes a mutable variable, then the assignment changes the current value of x to be the result of evaluating the expression e. The type of e is expected to conform to the type of x. If x is a parameterless function defined in some template, and the same template contains a setter function x_= as member, then the assignment x = e is interpreted as the invocation x_=(e ) of that setter function. Analogously, an assignment f .x = e to a parameterless function x is interpreted as the invocation f .x_=(e ). An assignment f (args) = e with a function application to the left of the ‘=’ operator is interpreted as f .update(args, e ), i.e. the invocation of an update function defined by f .

Furthermore, the getter must be visible in order to use the setter. I'm not sure if this is specified

Getter not visible #1

// error: method x cannot be accessed in x.Test
object x {
  class Test { 
    private[this] var x0: Int = 0
    private[Test] def x = x0
    def x_=(a: Int) = x0 = a 
  }
  val t = new Test
  t.x = 1
}

Getter not visible #2

//<console>:11: error: type mismatch; found   : x.Test required: ?{val x: ?}
object x {
  class Test { 
    private[this] var x0: Int = 0
    private[this] def x = x0
    def x_=(a: Int) = x0 = a 
  }
  val t = new Test
  t.x = 1
}

Getter visible

object x {
  class Test { 
    private[this] var x0: Int = 0
    private[x] def x = x0
    def x_=(a: Int) = x0 = a 
  }
  val t = new Test
  t.x = 1
}


As retronym pointed out, there must be a getter present. As a workaround however (if you don't want to provide a getter), you can make the getter return Unit

object x {
  class Test { 
    private[this] var x0: Int = 0
    def x: Unit = ()
    def x_=(a: Int) = x0 = a 
  }
  val t = new Test
  t.x = 1
}

Don't think that that is considered good style (!), but it works.

0

上一篇:

下一篇:

精彩评论

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

最新问答

问答排行榜