【问题标题】:Scala: can't write setter without getter?Scala:没有getter就不能写setter?
【发布时间】:2010-03-15 12:46:42
【问题描述】:

这行得通:

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(使用语法糖)?

【问题讨论】:

    标签: scala


    【解决方案1】:

    规范要求 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 定义的更新函数。

    此外,getter 必须可见才能使用 setter。我不确定这是否被指定

    吸气剂不可见 #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 不可见 #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
    }
    

    吸气剂可见

    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
    }
    

    【讨论】:

    • “Getter Visible”示例在 repl 中不起作用。 :14: 错误:类型不匹配;找到:x.type(带有底层类型对象 x) 需要:?{val x: ?}
    【解决方案2】:

    正如提要指出的那样,必须有一个吸气剂。但是,作为一种解决方法(如果您不想提供 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
    }
    

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

    【讨论】:

      猜你喜欢
      • 2017-09-07
      • 2017-01-01
      • 1970-01-01
      • 2014-10-03
      • 2014-11-18
      • 2012-09-10
      • 1970-01-01
      • 1970-01-01
      • 2012-06-09
      相关资源
      最近更新 更多