Scala闭包上下文
发布时间:2020-12-16 19:22:13 所属栏目:安全 来源:网络整理
导读:我不是Groovy专家,但我确实读过“Groovy in Action”一书.在Groovy中,每个闭包都带有一个“上下文”,其中闭包内的项可以访问伪变量,如“this”,“owner”和“delegate”,让项目知道谁调用了闭包.这允许人们编写这样的DSL(来自Groovy in Action): swing = ne
我不是Groovy专家,但我确实读过“Groovy in Action”一书.在Groovy中,每个闭包都带有一个“上下文”,其中闭包内的项可以访问伪变量,如“this”,“owner”和“delegate”,让项目知道谁调用了闭包.这允许人们编写这样的DSL(来自Groovy in Action):
swing = new SwingBuilder() frame = swing.frame(title:'Demo') { menuBar { menu('File') { menuItem 'New' menuItem 'Open' } } panel { // ... } } 请注意,’menuBar’“知道”它属于’frame’,因为它可以获取有关闭包的所有者和委托的上下文信息. 这可以在Scala中做到吗?如果是这样,怎么样? 解决方法
一种方法是使用
scala.util.DynamicVariable来跟踪上下文.像SwingBuilder这样的东西可以实现为
import scala.util.DynamicVariable import javax.swing._ object SwingBuilder { case class Context(frame: Option[JFrame],parent: Option[JComponent]) } class SwingBuilder { import SwingBuilder._ val context = new DynamicVariable[Context](Context(None,None)) def frame(title: String)(f: =>Unit) = { val res = new JFrame(title) res.add(new JPanel()) context.withValue(Context(Some(res),context.value.parent)){f;res} } def menuBar(f: =>Unit) = { val mb = new JMenuBar() context.value.frame.foreach(_.setJMenuBar(mb)) context.withValue(Context(context.value.frame,Some(mb))){f;mb} } def menu(title: String)(f: =>Unit) = { val m = new JMenu(title) context.value.parent.foreach(_.asInstanceOf[JMenuBar].add(m)) context.withValue(Context(context.value.frame,Some(m))){f;m} } def menuItem(title: String) = { val mi = new JMenuItem(title) context.value.parent.foreach(_.asInstanceOf[JMenu].add(mi)) } } object Test { def main(args: Array[String]) { val builder = new SwingBuilder() import builder._ val f = frame("Demo") { val mb = menuBar { menu("File") { menuItem("New") menuItem("Open") } } } f.setVisible(true) } } (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |