zoukankan      html  css  js  c++  java
  • 学习Groovy — 闭包

    定义闭包的几种方式

    map = ['a':1, 'b':2]
    // simple declaration, anonymous closure
    map.each{ key, value -> map[key] = value * 2}
    assert map == [a:2, b:4]
    
    // assignment to variables
    doubler = {key, value -> map[key] = value *2}
    map.each(doubler)
    assert map == [a:4, b:8]
    
    // use Clousure keyword to define a closure object
    def Closure doubling(){
        return {key, value -> map[key] = value *2}
    }
    map.each(doubling())
    assert map == [a:8, b:16]
    
    //instance method
    def doublemethod(entry) {
        map[entry.key] = entry.value*2
    }
    doubler2 = this.&doublemethod
    map.each(doubler2)
    assert map == [a:16, b:32]

    闭包的参数并不需要显式的定义。并且闭包中为参数显示指定的类型也只在运行时期检查而不是编译时期。

    闭包可以使用变长参数,和提供默认参数值。

    闭包类Closure中的方法

    2.1 call()方法

    2.2 getParameterTypes()方法: 获得闭包的参数信息

    2.3 curry()方法,用来为闭包的参数指定值后返回新的闭包

    2.4 isCase()方法,配合grep方法和switch块中的case分支

    理解闭包中的作用域(scoping)

    闭包的作用域为所有可以在闭包体内访问到的变量的总和,闭包的作用域定义了:

      a) 哪些本地变量可以访问

      b) this表示Closure本身

      c) 哪些fields和method可以从闭包内访问

    闭包有declarer(声明者)和caller(调用者)之分。在闭包内部,变量caller指向调用者,变量this.owner或者owner指向declarer。

    同时闭包的birthday context会被保留下来。同时在闭包内部调用任何方法会被代理(delegated to)到声明者上,即owner变量引用的对象。

    class Mother {
     int field = 1
     int foo(){
         return 2
     }
     Closure birth (param){
         def local = 3
         def closure = { caller ->
             [this, field, foo(), local, param, caller, owner]
         }
         return closure
      }
    }
    Mother julia = new Mother()
    closure = julia.birth(4)
    context = closure.call(this)
    
    // the 'this' reference
    println context[0].class.name
    println context[1..4]
    // the caller 
    println context[5].class.name
    // the owner here points to the declarer of the this closure.
    println context[6] == context[0]
    
    //output 
    Mother
    [1, 2, 3, 4]
    ConsoleScript4
    true
    

      

  • 相关阅读:
    springboot mybatis使注解和xml两种方式同时生效
    maven setting 配置仓库,pom.xml中repository不起作用
    k8s ocker-engine-selinux conflicts with 2:container-selinux-2.107-1.el7_6.noarch
    linux ,查看端口
    java,string和list,list和set相互转换
    sprintboot+mybatis+@Mapper中in的使用方法
    自动添加芝麻代理白名单的方法
    python 本地时间+8小时
    Android Studio镜像设置
    AndroidStudio初次使用
  • 原文地址:https://www.cnblogs.com/joshuajiang/p/5137058.html
Copyright © 2011-2022 走看看