了解Gradle之groovy概览
def的用途
用def定义的变量时无类型的变量,这里所说的无类型的变量,并不表示该变量就不属于某一个类型了,def修饰变量正是Groovy为动态语言的标记,大概def修饰变量就相当于Java中Object来修饰变量吧。如果通过使用def关键字使用可选类型,那么整数的类型将是可变的:它取决于这个类型实际包含的值。
assert a instanceof Integer
//assert a instanceof Long//错误
def b = 2147483648
assert b instanceof Long
关于函数的定义
如果所定义的函数没有参数,那么必须在调用的时候加上括号。
要有返回值的类型声明,如def、void、String等。
可以使用return返回值,若不写,则默认返回最后一行的值,没有则为null。
闭包是什么?
A closure in Groovy is an open, anonymous, block of code that can take arguments, return a value and be assigned to a variable. A closure may reference variables declared in its surrounding scope. In opposition to the formal definition of a closure, Closure in the Groovy language can also contain free variables which are defined outside of its surrounding scope.Apache Groovy Doc
语法与用法
{ println 'hi' }
{ name -> println name }
{ String x, int y ->
println "hey ${x} the value is ${y}"
}
{ reader ->
def line = reader.readLine()
line.trim()
}
// as an object
def listener = { e -> println "Clicked on $e.source" }
assert listener instanceof Closure
Closure callback = { println 'Done!' }
Closure<Boolean> isTextFile = {
File it -> it.name.endsWith('.txt')
}
//闭包是有返回值的,默认最后一行语句就是该闭包的返回值,如果最后一行语句没有不输入任何类型,闭包将返回null。
// 调用闭包
def code = { 123 }
assert code() == 123
assert code.call() == 123
访问外部变量
def str='hello world'
def closure={
println str
}
closure()
语法糖
- .闭包可作为一个参数传给另一个闭包,也可在闭包中返回一个闭包。
def timesThree = {
num -> num * 3
}
def runTwice = {
num, func -> func(func(num))
}
println runTwice(10,timesThree)
def times = {
x -> {
y -> x * y
}
}
println times(3)(4)
- 闭包的一些快捷写法.
- 当闭包作为闭包或方法的最后一个参数,可以将闭包从参数圆括号中提取出来接在最后。
- 如果闭包中不包含闭包,则闭包或方法参数所在的圆括号也可以省略。
- 对于有多个闭包参数的,只要是在参数声明最后的,均可以按上述方式省略。
闭包的Delegation代理
- this 指闭包所在的最近的类 .class
- owner 指定义闭包的宿主,不仅仅是类,还可能是一个闭包
- delegate 代理,默认使用的是owner
- delegate strategy 代理的代理策略
def p = new Person(name:'Jessica', age:42)
def t = new Thing(name:'Printer')
def cl = p.fetchAge
cl.delegate = p //设置代理
assert cl() == 42
cl.delegate = t
assert cl() == 42 //owner优先,fetchAge是一个闭包,它的owner是Person
cl.resolveStrategy = Closure.DELEGATE_ONLY //修改策略
cl.delegate = p
assert cl() == 42
cl.delegate = t
try {
cl()
assert false //呵呵,delegate上面没有该属性,报错
} catch (MissingPropertyException ex) {
// "age" is not defined on the delegate //没有定义
}
至此基本的东西差不多解决了。