Scala:没有 getter 就不能写 setter 吗?

发布于 2024-10-11 08:47:29 字数 619 浏览 1 评论 0原文

这有效:

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

但是我没有

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

val b = new ButtonCountObserver 
b.count = 0

得到: error: value count is not a member of ButtonCountObserver

是否可以创建一个没有 getter 的 setter(使用语法糖)?

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?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

猫性小仙女 2024-10-18 08:47:29

该规范要求定义 setter 和 getter 以便能够使用语法糖来调用 setter:

赋值给的解释
一个简单的变量 x = e 取决于
x 的定义。如果 x 表示
可变变量,然后赋值
将 x 的当前值更改为
评估的结果
表达式 e. e 的类型是
期望符合 x 的类型。
如果 x 是无参数函数
在某些模板中定义,并且相同
模板包含一个 setter 函数
x_= 作为成员,则赋值 x =
e 被解释为调用
该 setter 函数的 x_=(e )。

类似地,赋值 f .x = e 至
无参数函数 x 是
解释为调用 f .x_=(e
)。赋值 f (args) = e 和 a
左边的函数应用
'=' 运算符被解释为 f
.update(args, e ),即调用
由 f 定义的更新函数。

此外,为了使用 setter,getter 必须可见。我不确定是否指定了这个

Getter notvisible #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 notvisible #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
}

Gettervisible

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
}

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
}
复古式 2024-10-18 08:47:29

正如 Retronym 所指出的,必须有吸气剂存在。然而,作为一种解决方法(如果您不想提供 getter),您可以使 getter 返回 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
}

不要认为这被认为是好的风格(!),但它确实有效。

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文