我知道在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 +=
。但是,就我而言,我不能省略_
。为什么这与上面的二传手不同,我怎么能实现自己想要的?
答案 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]