具有Scala延续的事件侦听器

Mic*_*ael 5 user-interface continuations scala continuation-passing

假设我必须编写一些GUI代码,如下所示:

widget1.addListener(event1 =>
   handle1(event1)
   widget2.addListener(event2 =>
     handle2(event2)
     widget3.addListener(event3 => handle3(event3))
   )
)
Run Code Online (Sandbox Code Playgroud)

你会如何使用Scala延续以CPS风格编写它?

ten*_*shi 8

只是想提供其他答案之外的工作示例.使用Scala continuation,它看起来像这样:

import scala.util.continuations._

object ContinuationsExample extends App {
  val widget1 = Widget()
  val widget2 = Widget()

  reset {
    val event1 = widget1.getEvent
    println("Handling first event: " + event1)
    val event2 = widget2.getEvent
    println("Handling second event: " + event2)
  }

  widget2 fireEvent Event("should not be handled")
  widget1 fireEvent Event("event for first widget")
  widget2 fireEvent Event("event for second widget")
  widget1 fireEvent Event("one more event")
}

case class Event(text: String)

case class Widget() {
  type Listener = Event => Unit
  var listeners : List[Listener] = Nil

  def getEvent = shift { (l: Listener) =>
    listeners = l +: listeners
  }

  def fireEvent(event: Event) = listeners.foreach(_(event))
}
Run Code Online (Sandbox Code Playgroud)

这段代码实际上是编译和运行的,所以你可以自己尝试一下.您应该收到以下输出:

Handling first event: Event(event for first widget)
Handling second event: Event(event for second widget)
Handling first event: Event(one more event) 
Run Code Online (Sandbox Code Playgroud)

如果您将编译此示例,那么不要忘记通过为-P:continuations:enableScala编译器提供参数来启用continuation .