Groovy(Java笨狗)系列---closures(四)

(一)Closures(闭包):

   使Groovy与其他大多数编程序语言不同的是---它能创造头等对象的functions(注:原文that you can create functions that are first class objects  我对这句话理解不是很深,所以写上原文,以免误人,如果大家对这句话有好的理解,希望能在评论上给予指正)。换句话说,你可以定义一个代码块,然后把它看作是一个字符串或是整数来传递。

Code(1):

square = { it * it }

 Groovy编辑器会把上面这段用大括号围绕着it*it的表达式会看成代码。在软件世界里,这样的形式被叫做“closure(闭包)”。标识符"it"代表function中给定的任何值。

Code(2):

square(9)

 现在我们传递一个Number为9的数字到“闭包”square(),大家可以简单的理解下:先定义一个闭包Code(1);

it在这里可以看作是闭包中的参数,代表任何值,然后执行你想要的操作,上面是it*it。定义完“闭包”后,你就可以使用“闭包”,

Code(2)传递给“闭包”9,它的返回结果为81.到这里,大家应该对“闭包”能简单理解了。

 

上面这些可能都不会让你产生兴趣,当你知道闭包是可以作为值来传递的,你就不会这样想了。Groovy有些内置的函数(functions),这些函数的参数可以使用其他的函数作为参数。

Code(3):

[ 1, 2, 3, 4 ].collect(square)

 在上面的实例当中,创建了一个值为[1,2,3,4]的array。然后调用方法collect().并把上面定义的闭包作为参数。

现在我们来理解下:array中的每个元素都会调用collect(),然后每个元方素又作为闭包的参数来执行闭包里的法it*it。返回的结果为[1,4,9,16],可能看结果更直接点。。。

当然,Groovy中还有更多这样的方法使用闭包作为参数。

 

默认的情况下,Groovy使用一个叫“it”的参数,你也可以使用指定的参数来创建闭包。现在使用Map.each()作为实例让闭包带有两个变量,来广联Map中的key,Value。

printMapClosure = { key, value -> println key + "=" + value }
[ "yue" : "wu", "lane" : "burks", "sudha" : "saseethiaseeleethialeselan"
].each(printMapClosure)

 上面可以看出

先定义一个闭包

printMapClosure = { key, value -> println key + "=" + value }

 他的作用是输出Map中Key,Value的值,形式是key=Value.

输出结果为:

yue=wu
lane=burks
sudha=saseethiaseeleethialeselan

 当然还有更多的关于闭包的实例,比如这里

fullString = ""
orderParts = ["BUY", 200, "Hot Dogs", "1"]
orderParts.each {
fullString += it + " "
}
println fullString

 

myMap = ["asdf": 1 , "qwer" : 2, "sdfg" : 10]
result = 0
myMap.keySet().each( { result+= myMap[it] } )
println result

 

好了了解了基本的闭包,现在来看下使用闭包来出来File吧。

 

 

在Groovy中使用闭包读取File文件是相当的简单。

Code:

myFileDirectory = "C:\\temp\\"
myFileName = "myfile.txt"
myFile = new File(myFileDirectory + myFileName)
printFileLine = { println "File line: " + it }
myFile.eachLine( printFileLine )
  • 先定义文件夹路径变量
  • 定义实际要读取的文件变量
  • 新建File对象
  • 定义一个具有读取每行文件功能的闭包
  • 调用File对象的方法eachLine(),并把闭包{println "file line:"+it}作为参数

执行上面的代码后,将显示你读取的myfile.txt的每一行。

如果你正在跟着这个系列的脚步,可以自己运行上面的实例,加深对闭包的理解。

 

看了这么多实例,再看下闭包的定义好了(根据官方的文档,现在这个部分不是放在起步文档里,不过想提前翻译给大家,加深对闭包的了解)

  • 闭包可以被看作代码块或者方法指示器。
    def clos = { println "hello! }
    println "Executing the closure:"
    clos() //prints "hello!"
     
  • 闭包的参数放置于->号之前
    def clos = { a, b -> print a+b }
    clos( 5, 7 ) //prints "12"
     假如你的参数少于2个的话,参数和->是可以省略,如上面的代码。
  • 在闭包中包含了几个内置的标量,他们代表了特定的含义:
  1. It:这个是闭包的默认值, 假如你的参数少于2个的话。
    def clos = { print it }
    clos( "hi there" ) //prints "hi there"
     
  2. this : 在Java中, 指向定义了闭包的封装类
  3. owner : 封装类中的闭包
  4. delegate : 和owner,但也存在变化,会在以后讲解
    class Class1 {
    def closure = {
    println this.class.name
    println delegate.class.name
    def nestedClos = {
    println owner.class.name
    }
    nestedClos()
    }
    }
    def clos = new Class1().closure
    clos.delegate = this
    clos()
    /* prints:
    Class1
    Script1
    Class1$_closure1 */
     
  • 闭包就是对象
  • 闭包作为方法的参数
    def list = ['a','b','c','d']
    def newList = []
    list.collect( newList ) {
    it.toUpperCase()
    }
    println newList // ["A", "B", "C", "D"]
     
    def list = ['a','b','c','d']
    def newList = []
    def clos = { it.toUpperCase() }
    list.collect( newList, clos )
    assert newList == ["A", "B", "C", "D"]

更多闭包的信息可以从官网查看,当然在后面也会对闭包做更详细的说明(按照官方文档的来翻译的,大家不了解的先==吧)。

 

 

 

你可能感兴趣的:(java,C++,c,C#,groovy)