名称中带有空格的定义方法

时间:2019-01-15 21:22:39

标签: scala

我知道在Scala中我可以这样编写getter / setter:

class Person() {
 // Private age variable, renamed to _age
 private var _age = 0
 var name = ""

 // Getter
 def age = _age

 // Setter
 def age_= (value:Int):Unit = _age = value
}

其中_中的def age_=表示空白。 (Source

遵循这个原则,我想写这样的东西:


object SubjectUnderObs {
  var x: Int = 0

  private var myListeners : Set[Int => Unit] = Set()

  def listeners_+= (listener: Int => Unit): Unit =
    myListeners = myListeners + listener
}

// This does not compile
SubjectUnderObs.listeners += { newX =>
  println(newX)
}

我基本上想使用以下语法添加回调:SubjectUnderObs.listeners +=。但是,就我而言,我不能省略_。为什么这与上面的二传手不同,我怎么能实现自己想要的?

2 个答案:

答案 0 :(得分:4)

首先,以_=结尾的方法是表示设置器的特殊方法。这就是为什么下划线仅在您认为这种情况下才起作用的原因。

现在,您可以通过公开var listeners: Set[Int => Unit]来获得所需的行为,但是人们可以做其他事情,例如删除侦听器。您可以改为使侦听器成为定义+=方法的对象:

object listeners {
  def +=(listener: Int => Unit): Unit =
    myListeners += listener
  }
}

将其放在SubjectUnderObs内,它应该可以工作。

答案 1 :(得分:2)

对于方法名称,用_更改并没有一般规则。
在您的第一个示例中,发生的是一个语法糖规则。

  

a.b = c等效于a.b _ =(c)。在类/对象中创建val / var x时,Scala会为您创建方法x和x_ =。
  -Source

如果只有一个这样的方法(例如,仅侦听器),则可以定义一个+=方法来接受Listener,我不确定是否会对您来说足够可读。

另一种选择是使用嵌套对象提供所需的 DSL

final class SubjectUnderObs { self =>
  private[this] var _listeners: List[Int] = List.empty

  object ListenersMutator {
    def += (listener: Int): Unit = {
      self._listeners = listener :: self._listeners
    }
  }

  def listeners = ListenersMutator

  override def toString: String =
    _listeners.mkString("[", ", ", "]")
}

val res1 = new SubjectUnderObs
// res1: SubjectUnderObs = []

res1 += 10
// res1: SubjectUnderObs = [10]