[英]Scala: store call-by-name variable as class field
In my progress in Scala learning I try to implement a simple DSL with callbacks 在Scala学习的过程中,我尝试使用回调实现简单的DSL。
object Button {...} // apply
class Button(val name: String) {
private val: => Unit; // doesn't work
def click(f: => Unit) = {
_click_cb = f
this
}
def onClick() = this._click_cb()
}
Button("Click me!") click {println("Clicked!")}
I create a new object, pass it a callback to store. 我创建一个新对象,向其传递一个回调以进行存储。 My demo framework fires
onClick
method, that should call the stored one 我的演示框架触发了
onClick
方法,该方法应调用存储的
It works with () => Unit
but my DSL looks ugly: 它可以与
() => Unit
但是我的DSL看起来很丑:
Button("Click me!") click (() => println("Clicked!"))
Sure, I could do onClick
abstract and implement an anonymous class later 当然,我可以做
onClick
抽象并稍后实现一个匿名类
new Button("Click me!") {def onClick = println("Clicked!")}
But I want to play with some DSL and such 但是我想玩一些DSL之类的游戏
The questions are: 问题是:
f
in _click_cb
? f
存储在_click_cb
? _click_cb
? _click_cb
提供初始“空”功能? An uglier version just to show that lazy val can hold the by name parameter value without evaluating it: 一个更丑陋的版本,只是为了显示惰性val可以保留by name参数值而不对其求值:
case class Button(val name: String) {
def clickCallback(): Unit = ()
def click(f: => Unit) = {
lazy val notEvaluated = f
new Button(name) { override def clickCallback() = notEvaluated }
}
def onClick(): Unit = clickCallback()
}
A cleaner and more functional implementation: 更干净,功能更强大的实现:
class Button(val name: String) {
def click(f: => Unit) = new Button(name) { override def onClick() = f }
def onClick(): Unit = ()
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.