加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 综合聚焦 > 服务器 > 安全 > 正文

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)
  }
}

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读