groovy 闭包和函数

  1. 为什么要使用闭包
# 参考
https://juejin.cn/post/6844903878111019022



# 闭包模板
def closure4 = { x, y -> println("x is ${x}, y is ${y}") } // 省略类型
Closure closure6 = { println('Done') } // 声明类型Closure
Closure<Boolean> closure7 = { int a, int b -> a == b } // 可以定义返回类型
# 函数
// def isOdd = { int i -> i%2 != 0 }
// println(isOdd(3))
# 闭包
def isOdd(def i){
  return i%2 != 0
}
println(isOdd(3))




# 为什么要使用闭包
Groovy 中的闭包避免了代码的冗长,可以辅助创建轻量级、可复用的代码片段。下面举个简单的例子带大家体验一下闭包的便捷性。
例子:求 1 到 n 之间的所有奇数的和。
传统实现中,我们定义一个 sum 方法,其中使用 for 循环实现奇数的累加,代码如下:
def sum(n) {
    total = 0
    for (int i = 1; i <= n; i += 2) {
        // 计算1到n的奇数和
        total += i
    }
    total
}

println(sum(9)) // n等于9
如果改成计算所有奇数的乘积呢?那又得定义一个 multiply 方法,还是使用 for 循环实现,代码如下:
def multiply(n) {
    total = 1
    for (int i = 1; i <= n; i += 2) {
        // 计算1到n的奇数乘积
        total *= i
    }
    total
}
如果再换成求奇数的平方和呢?实现代码基本与 sum 和 multiply 一致,重复的 for 循环,不同的计算方式而已。
仅仅是三种情况就定义了三个方法,而且存在大量重复代码,这种实现太不优雅了。那使用闭包实现呢?我们只需要定义一个高阶函数,传入一个 Closure 参数即可。
def pickOdd(n, closure) { // 此处的closure可以换成别的参数名
    for (int i = 1; i <= n; i += 2) {
        // 执行逻辑都由传入的闭包决定
        closure(i)
    }
}
Groovy 的闭包可以附在一个方法上或者赋值给一个变量。示例中变量 closure 就保持了一个指向闭包的引用。使用 pickOdd 方法的时候传入包含不同逻辑的闭包方法块即可。
// 打印奇数
pickOdd(9) {
    println it // 下文会详细介绍it
}

// 求和
total = 0
pickOdd(9, {
    num -> total += num // 可以访问total变量
})
println("Sum of odd is: ${total}")
显然,通过闭包实现不仅在语法上比传统方式更优雅,还为函数将部分实现逻辑委托出去提供了一种简单、方便的方式。




  1. DSL
# 一个DSL脚本就是一个闭包。
https://lesofn.com/archives/shi-yong-groovy-gou-jian-dsl


detailInfo = [:]

def methodMissing(String name, args) {
    detailInfo[name] = args
}

def introduce(closure) {
    closure.delegate = this
    closure()
    detailInfo.each {
        key, value ->
            println "My $key is $value"
    }
}

introduce {
    name "zx"
    age 18
}
  1. 函数
https://www.w3cschool.cn/groovy/groovy_methods.html

# 没有参数
def methodName() { 
   //Method code 
}

# 带参数
def someMethod(parameter1, parameter2 = 0, parameter3 = 0) { 
   // Method code goes here 
} 

  1. 闭包
https://www.w3cschool.cn/groovy/groovy_closures.html

# 没有参数
def clos = {println "Hello World"};
clos.call();

# 带参数
def clos = {param->println "Hello ${param}"};
clos.call("World");
posted @ 2021-07-19 13:28  该显示昵称已被使用了  阅读(84)  评论(0编辑  收藏  举报