Scala:将按名称调用的变量存储为 class 字段

Scala: store call-by-name variable as class field

在我学习 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!")}

我创建了一个新对象,将回调传递给它进行存储。我的演示框架触发 onClick 方法,应该调用存储的

它适用于 () => Unit 但我的 DSL 看起来很丑:

Button("Click me!") click (() => println("Clicked!"))

当然,我可以做 onClick 抽象并稍后实现匿名 class

new Button("Click me!") {def onClick = println("Clicked!")}

但我想玩一些 DSL 之类的东西

问题是:

一个更丑陋的版本只是为了表明 lazy 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()
}

更简洁、更实用的实现:

class Button(val name: String) {
  def click(f: => Unit) = new Button(name) { override def onClick() = f }

  def onClick(): Unit = ()
}