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

Groovy 闭包学习笔记

发布时间:2020-12-14 16:48:52 所属栏目:大数据 来源:网络整理
导读:1.??????闭包的初步认识 闭包通常用于函数式语言中,它允许执行一个制定好的代码块。 通俗的说,一个闭包就是一个用花括号括起来的语句块,为了传递参数给闭包,闭包有一个可选的参数列表,通过“-”表示列表的结束 闭包的简单实例: 面向对象的最高原则是对

1.??????闭包的初步认识

闭包通常用于函数式语言中,它允许执行一个制定好的代码块。

通俗的说,一个闭包就是一个用花括号括起来的语句块,为了传递参数给闭包,闭包有一个可选的参数列表,通过“->”表示列表的结束

闭包的简单实例:

面向对象的最高原则是对象有自己的行为和数据,闭包也是对象,其目的是其行为。可以把闭包理解为一个类中的方法。但是始终记住:闭包是由一些代码组成的对象。

2.??????闭包的缺省参数it

下面两个closure作用是一样的

[1,2,3].each{println it}
[1,3].each{i->println i}

等效的java代码:

List<Integer> list=new ArrayList<Integer>();
list.add(1);
list.add(2);
list.add(3);
for(Integer i:list){
    System.out.println(i);
}

3. 闭包的用途

???????? 3.1 处理集合,迭代

?????????????????? 上面的例子都是关于集合的实例

???????? 3.2 处理资源

?????????????????在Java中打开流必须对应一个close来关闭流来释放资源。通过groovy闭包可以实现:

???????? newFile("D:carinfo.txt").eachLine { println it }

eachLine会处理流的打开及关闭。

4. 声明闭包

???????? 4.1?花括号声明

在一个方法调用的后面,放置闭包代码在一对花括号里,闭包的参数和代码通过箭头进行分割。箭头是闭包的参数和代码的分隔指示符。

???????? 4.2?声明变量

使用复制的方式声明闭包,将其赋给一个变量。

???????? def printer={line -> println line}

???????? 4.3?方法返回值

通过方法返回值

         def Closure getPrinter(){
   		return {line -> println line}
	}

???????? 4.4 引用一个方法作为闭包

???????? 重用已有的声明:一个方法。方法有一个方法体,可选的返回值,能够接受参数,并且能被调用。调用方法:

class MethodClosureSample{
    int limit

    MethodClosureSample(int limit){
        this.limit=limit
    }

    boolean validate(String value){
        return value.length()<=limit
    }
}

MethodClosureSample first=new MethodClosureSample(6)
MethodClosureSample second=new MethodClosureSample(5)

Closure firstClosure=first.&validate

def words=["long string","medium","short","tiny"]

println(words.find(firstClosure))
println(words.find(second.&validate))

4.5 闭包缺省参数

def adder={x,y=5->return x+y}
println(adder(4,3))   //直接调用
println(adder.call(2)) //call方式调用

5.闭包的调用

?直接调用和使用call方法调用

实例1:

def adder={x,y->return x+y}
println(adder(4,3))   //直接调用
println(adder.call(2,6)) //call方式调用

实例2:从一个方法内部调用一个闭包

def benchmark(repeat,Closure worker){
    start=System.currentTimeMillis()
    repeat.times{worker(it)}
    stop=System.currentTimeMillis()
    return stop-start
}

slow=benchmark(10000){(int)it/2}
fast=benchmark(10000){it.intdiv(2)}
println(fast)
println(slow)

6.curry

curry的基本思想是一个多个参数的函数,传递较少的参数给函数来固定一些值。

在groovy中,Closure的curry方法返回当前闭包的一个克隆品,这个克隆品已经绑定一个或多个给定的参数。

def adder={x,y->return x+y}
def addCurry=adder.curry(1)
println(addCurry(6))

一个复杂的例子:

def configurator={format,filter,line->
    filter(line)?format(line):null
}

def appender={config,append,line->
    def out=config(line)
    if(out)append(out)
}

def dateFormatter={line->"${new Date()}:$line"}
def debugFilter={line->line.contains('debug')}
def consoleAppender={line->println line}

def myConf=configurator.curry(dateFormatter,debugFilter)
def myLog=appender.curry(myConf,consoleAppender)

myLog("here is some debug message")
myLog("this will not be printed")

7.变量作用域

def x=0

10.times {x++}

println x

花括号显示了闭包声明的时间,不是执行的时间。在闭包的声明期间,闭包可以对变量x进行读和写操作(没理解这句的意思

)。


闭包在它的生命周期里以某种方式记住了它的工作上下文环境,当调用它时,闭包可以在它的原始上下文中工作。

这种声明周期的上下文需要闭包记住相应地一个引用,而不是一个复制品,如果工作上下文是原始上下文的一个复制品,

从闭包中是没有办法改变原始上下文的。声明周期上下文必须被引用。


在闭包中,this将引用到当前对象,这是对包对象本身。

名称为owner的变量可以获取到声明闭包的对象。

?

8.从闭包返回结果

????????闭包最后一个表达式执行的结果,并且这个结果被返回,叫做结束返回,在最后的语句前面的return关键字是可选的。

????????使用return关键字从闭包的任何地方返回

????????在闭包内使用return关键字和在闭包外使用是有区别的。在闭包内使用return,仅结束闭包的当前计算,例如在list.each中,return不影响闭包在下一个元素时被调用


ps:《Groovy in action》读书笔记

(编辑:李大同)

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

    推荐文章
      热点阅读