Android Groovy 闭包(六)

首先申明下,本文为笔者学习《Groovy 程序设计》的笔记,并加入笔者自己的理解和归纳总结。

闭包是Groovy的特性之一,类似于Java中的匿名内部类,但功能更加强大。

1. 闭包应用

一般用法

def filter(array, block) {
    for (val in array) {
        block(val)
    }
}

iarray = [1, 2, 3, 4, 5, 6, 7, 8, 9]
total = []
filter(iarray, { if (it % 2 == 0) total << it })
println total // [2, 4, 6, 8]

total = []
filter(iarray, { if (it > 5) total << it })
println total // [6, 7, 8, 9]

当闭包作为最后一个参数时,可以有其它写法

filter(iarray) { if (it % 2 == 0) total << it }

闭包也可以作为属性,可以判断是否提供。

class Person {
    def block
    def setBlock(b) {
        block = b;
    }
    def doSomeThing() {
        if (block) {
            block()
        } else {
            println "no block provide"
        }		
    }
}
def p1 = new Person()
p1.doSomeThing() // no block provide

def block = { println "in block" }
def p2 = new Person()
p2.setBlock(block)
p2.doSomeThing() // in block

2. 闭包参数

单个参数it就是默认的参数名, 也可以指定特定的名称。

def printWithOneParameter(block) {
    block("Michael")
}
printWithOneParameter { println it } // Michael
printWithOneParameter { name -> println name } // Michael

多个参数

def printWithTwoParameter(block) {
    block "Michael", "Jordan"
}
printWithTwoParameter { firstName, secondName ->
    println "$secondName, $firstName $secondName"
}

返回

Jordan, Michael Jordan

预先绑定相应的参数

def printWithTwoParameter(block) {
    newBlock = block.curry("Michael")
    newBlock "Jordan"
    newBlock "Jackson"
}

printWithTwoParameter { firstName, secondName ->
    println "$secondName, $firstName $secondName"
}

返回

Jordan, Michael Jordan
Jackson, Michael Jackson

类似的方法还有rcurry()ncurry()

def printWithTwoParameter(block) {
    newBlock = block.rcurry("Michael")
    newBlock "Jordan"
    newBlock "Jackson"
}

printWithTwoParameter { firstName, secondName ->
    println "$secondName, $firstName $secondName"
}

返回

Michael, Jordan Michael
Michael, Jackson Michael

ncurry()调用格式是ncurry(index, block)

maximumNumberOfParameters属性,闭包参数的数量。

def printWithTwoParameter(block) {
    println block.maximumNumberOfParameters
}

printWithTwoParameter { firstName, secondName ->
    println "$secondName, $firstName $secondName"
}

返回2

3. 闭包委托

闭包的三个属性thisownerdelegate,用来确定那个对象处理该闭包的方法调用。

在内部的闭包中,ownerdelegate的值被修改了。

def parameterClosure(closure) {
    closure()
}
parameterClosure() {
    println "In Outer Closure"
    println "this is " + this
    println "owner is " + owner
    println "delegate is " + delegate

    parameterClosure() {
        println "In Inner Closure"
        println "this is " + this
        println "owner is " + owner
        println "delegate is " + delegate
    }
}

返回

In Outer Closure
this is ConsoleScript37@1372443
owner is ConsoleScript37@1372443
delegate is ConsoleScript37@1372443
In Inner Closure
this is ConsoleScript37@1372443
owner is ConsoleScript37$_run_closure1@3acd6fbe
delegate is ConsoleScript37$_run_closure1@3acd6fbe

类中调用闭包时,thisownerdelegate三个属性的值都是上下文。

class ParameterClosure {
    def handleClosure(closure) {
        closure()
    }
}
new ParameterClosure().handleClosure () {
    println "this is " + this
    println "owner is " + owner
    println "delegate is " + delegate
}

返回

this is ConsoleScript43@1d476b4b
owner is ConsoleScript43@1d476b4b
delegate is ConsoleScript43@1d476b4b

方法的执行顺序,首先是this,其次是owner,最后是delegate。可以设置delegate来修改路由。

class Handler {
    def f1() {
        println "f1 in Handler"
    }
    def f2() {
        println "f2 in Handler"
    }
}
class ParameterClosure {
    def handleClosure(closure) {
        closure.delegate = new Handler()
        closure()
    }
}
def f1() {
    println "f1 in script"
}
new ParameterClosure().handleClosure () {
    f1()
    f2()
}

返回

f1 in script
f2 in Handler

4. 上下文

上下文with

array = [1, 2, 3]
array.with {
    add(5)
    println delegate // [1, 2, 3, 5]
    remove(1)
    println delegate // [1, 3, 5]
}

设置delegate实现上下文。

def withClosure(closure) {
    array = [1, 2, 3]
    closure.delegate = array
    closure()
}
withClosure {
    add(5)
    println delegate // [1, 2, 3, 5]
    remove(1)
    println delegate // [1, 3, 5]
}

方法可以省略括号

def withClosure(closure) {
    array = [1, 2, 3]
    closure.delegate = array
    closure()
}
withClosure {
    add 5
    println delegate // [1, 2, 3, 5]
    remove 1
    println delegate // [1, 3, 5]
    remove 1
    println delegate // [1, 5]
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值