zoukankan      html  css  js  c++  java
  • Groovy 闭包深入浅出 终点就是起点 ITeye技术网站

    Groovy 闭包深入浅出 - 终点就是起点 - ITeye技术网站

    闭包概念

    Groovy语言中闭包(closure)是一个非常重要的概念,而且深入的理解了闭包对充分用好Groovy有很大帮助。对闭包比较书面的一种解释“闭包是可以用作函数参数和方法参数的代码块”。其实Groovy的闭包更象是一个“代码块”或者方法指针,代码在某处被定义然后在其后的调用处执行。

    现在支持闭包的语言有 Scheme、Common Lisp、Smalltalk、Groovy、JavaScript、Perl,Ruby 和 Python 。

    闭包基础
    来看一个例子:

    def square = {it * it} // 定义一个叫square的闭包。it是默认的 参数名称

    assert 4 == square(2) // 使用闭包

    assert [1,4,9] == [1,2,3].collect(square) // 使用闭包


    闭包类似Java的内类,区别是闭包只有单一的方法可以调用,但可以有任意的参数,闭包用“{}”括起,“->”前面是参数,后面是处理语句,可以直接调用,也可以使用call调用。不管那种调用,最后groovy编译器都会把编译成对doCall方法的调用,这是groovy对闭包的一个隐藏方法。

    def closure = { param -> println("hello ${param}") }
    closure.call("world!")
     
    def closure = { greeting, name -> println(greeting + name) }
    closure.call("hello ", "world!")

    第一个例子演示了在字符串内使用参数的形式:${param}
    第二个例子演示了多参数形式:用“,”分隔参数

    如果你的参数少于2个,那么它可以直接忽略掉。如果只有一个参数,可以不写,而使用缺省的参数“it”,如下面的例子:

    closure = { println "hello " + it }
    closure.call("world!")

    把闭包当作变量返回的例子:
    def localMethod() {
      def localVariable = new java.util.Date()
      return { println localVariable }
    }
     
    def clos = localMethod()
     
    println "Executing the closure:"
    clos() 

    Groovy闭包中几个隐含变量

    it:默认的参数名,调用是如果没有传参数,it为null
    this : 跟Java一样,是定义闭包所在类的一个引用,不管有多少层闭包嵌套,this指向的都是最上层的类。
    owner : 封闭闭包的对象(如果只有一层闭包就是this,如果有多层闭包嵌套就是含有此闭包的上层闭包)
    delegate :缺省值是owner,但是可以改变,后面详说。
    看例子:

    class Class1 {
      def closure = {
        println " ============================== "
        println "this = "+ this.class.name
        println "owner = " + owner.class.name
        println "delegate = " + delegate.class.name
        def nestedClos = {
            println " ============================== "
            println "this = "+ this.class.name
            println "owner = " + owner.class.name
            println "delegate = " + delegate.class.name
          def thirdClos = {
                println " ============================== "
                println "this = "+ this.class.name
                println "owner = " + owner.class.name
                println "delegate = " + delegate.class.name
          }
          thirdClos() 
        }
        nestedClos()
      }
    }
     
    def clos = new Class1().closure
    //clos.delegate = this
    clos()

    执行结果:
     ==============================
    this = Class1
    owner = Class1
    delegate = Class1
     ==============================
    this = Class1
    owner = Class1$_closure1
    delegate = Class1$_closure1
     ==============================
    this = Class1
    owner = Class1$_closure1_closure2
    delegate = Class1$_closure1_closure2

    闭包实现接口

    前面说了用闭包实现类,或继承其他类。现在看看怎么实现接口。


    interface Test
    {
     def test()
    }
     
     
    def test = {
     println'ok'
    } as Test
        
    test.test()
    如果接口只有一个方法需要实现,比如Comparator,Runnable等接口就可以直接实现方法后加上 as Runnable接口名就可以。

    多方法接口,groovy用Map的方法实现。

    interface MultiFuncTest
    {
        def test1()
        def test2(str)
    }
     
     
    def impl = [test1:{println'test'},
            test2:{str -> println str}] as MultiFuncTest


    impl.test1()
    impl.test2('ok')


    delegate委托的用法
    delegate委托在是一种常用设计模式,但在java中实现相对比较繁琐,groovy直接在GroovyObject中已经实现了delegate模式,所以在groovy中应用delegate很方便。

    class Dog{
        def play = {
          "wang wang!"
        }
        def childmind = {
            println       delegate.play();     
        }
    }

    class Cat {
        def play = {"mi mi !"}
    }

    def dog = new Dog()
    def cat = new Cat()

    dog.childmind()

    dog.childmind.delegate  = cat;
    dog.childmind()

    上面的例子是狗爸爸让老猫帮忙照看他的狗儿子玩游戏。

    闭包是Groovy一种核心技术,也是现在比较流行的动态语言的核心技术,所以全面稳定的掌握闭包是非常必要的。


    参考:
    http://blog.csdn.net/hivon/archive/2008/04/23/2318760.aspx  Groovy探索之闭包 三
    http://www.chinagroovy.org/groovywiki/doku.php/wiki:user_guide:closures Groovy文档翻译,什么是闭包

  • 相关阅读:
    Spring经典视频教程大集合
    使用jsonlib进行Java和JSON之间的转换
    c:import Unable to get RequestDispatcher for Context
    打开IE都会弹出欢迎界面“欢迎使用Internet Explorer 8”
    Struts2 标签 用法示例 (
    as3相关的frameworks
    as相关的框架引擎应用集合
    init
    XNA框架基础——疑难解答
    XNA框架基础——XNA的注意事项
  • 原文地址:https://www.cnblogs.com/lexus/p/2650846.html
Copyright © 2011-2022 走看看