欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

Gradle系列三之Groovy基本语法

程序员文章站 2022-07-12 15:10:45
...

由于是学习Groovy基础语法,开始我选择的IDE是Intellij IDEA,大家可以选择其它IDE,但是都需要配置Groovy环境变量和Java环境变量,这里就不一一赘述了。

Groovy中变量

Groovy没有基本类型,对于一些像int类型都会被包装成对象类型Integer

int x = 1
println(x.class)

def y = 3.14
println(y.class)

y = 'hello groovy'
println(y.class)

打印输出如下:

class java.lang.Integer
class java.math.BigDecimal
class java.lang.String

如果一个变量只在本类使用,可以直接用def去定义该变量;如果该变量还被其他类使用,那么最好还是直接用具体的类型定义该变量,而不是用def去定义。

Groovy中字符串
def name = 'name one'
def doubleName = "name double"
def tripleName = '''name triple'''
println name.class
println doubleName.class
println tripleName.class

打印输出如下:

class java.lang.String

也就是说,在一般的情况下,这三者都是可以表示字符串的,但是也有部分区别,比如:

def sayHello = "Hello: ${name}" //可扩展做任意的表达式
println sayHello.class
println sayHello

打印输出如下:

class org.codehaus.groovy.runtime.GStringImpl
Hello: name one

只有双引号才可以做这种扩展,注意这里的类型是GStringImpl,也就是GString的实现类。
对于三引号,也有其他两者做不到的,比如,按照某个规则显示:

def tripleName = '''\
line one
line two
line three\
'''

打印输出如下:

line one
line two
line three

对于一些字符串方法,字符串填充center、padLeft;比较大小str > str2;reverse()、capitalize()、isNumber(),这些方法在这里就不做赘述了,大家可以自行尝试。

逻辑控制

由于这里if/else和while循环和Java程序使用相似,故这里只选switch/case和for循环来讲。

  1. switch/case
def n = 1.23
def result
switch (n) {
    case 'hello':
        result = 'find hello'
        break
    case 'groovy':
        result = 'find groovy'
        break
    case [1, 2, 3, 'hello groovy']:  //列表
        result = 'find list'
        break
    case 12..30:
        result = 'find range'    //范围
        break
    case Integer:
        result = 'find integer'
        break
    case BigDecimal:
        result = 'find bigDecimal'
        break
    default:
        result = 'find default'
        break
}
println result

打印输出如下:

find bigDecimal
for循环
def sum = 0
for (i in 0..9) {
    sum += i
}

sum = 0
//对List的循环
for (i in [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]) {
    sum += i
}

sum = 0
//对Map进行循环
for (i in ['合肥':1, '杭州':2, '南京':3]) {
    sum += i.value
}
println sum
闭包

闭包是Groovy的一个非常重要的特性,可以说它是DSL的基础。闭包不是Groovy的首创,但是它支持这一重要特性,这就使代码灵活、轻量、可复用,再也不用像Java一样动不动就要用一个类了。

def clouser = {
    println 'Hello groovy!'
}

这种写法就是闭包,我们可以怎样调用闭包呢?

clouser.call()
clouser()

上面这两种写法都可以调用闭包。闭包内还可以传入参数:

def clouser = {String language ->
    println "Hello $language"
}

闭包内默认有一个it值,用于默认参数:

def clouser = {
    println "Hello ${it}"
}
clouser.call('groovy!')
clouser('groovy!')

闭包一定是有返回值的,而且默认是花括号中的最后一行:

def clouser = {String language ->
    "Hello ${language}"
}
def word = clouser('groovy!')
println word

打印输出如下:

Hello groovy!

接下来我们来验证返回值是否就是花括号的最后一行:

def clouser = {String language ->
    "Hello ${language}"
    'Hello Java!'
}
def word = clouser('groovy!')
println word

打印输出如下:

Hello Java!

输出结果也就验证了花括号的最后一行就是返回值。

闭包的使用

求累积:

int fun(int number) {
    def result = 1
    1.upto(number, {num -> result *= num})
    return result
}
println fun(5)

还可以这样写:

int fun(int number) {
    def result = 1
    1.upto(number) {
        num -> result *= num
    }
    return result
}

求累加:

int fun2(int number) {
    def result = 1
    number.times {
        num -> result += num
    }
    return result
}
println fun2(5)

要注意,这里只是累加到4,也就是1+0+1+2+3+4 = 11

字符串与闭包结合使用

1.字符串的each函数:

def str = 'the 2 add 3 is 5'
str.each {
    temp -> print temp
}

打印输出如下:

the 2 add 3 is 5

2.字符串的find函数:

def finder = str.find {
    it.isNumber()
}
println finder

打印输出如下:

2

也就是说find函数式查找字符串中符合闭包条件的第一个元素,找到了就直接返回。

3.字符串的findAll函数:

println str.findAll {
    it.isNumber()
}

打印输出如下:

[2, 3, 5]

4.字符串的any函数:

println str.any {
    it.isNumber()
}

打印输出如下:

true

只要有一个元素符合闭包的条件,就返回true

5.字符串的every函数:

println str.every {
    it.isNumber()
}

打印输出如下:

false

当所有的元素都符合闭包条件的时候,才返回true

6.字符串的collect函数:

println str.collect {
    it.toUpperCase()
}

打印输出如下:

[T, H, E,  , 2,  , A, D, D,  , 3,  , I, S,  , 5]
闭包进阶

闭包的三个重要变量:this、owner、delegate

def scriptClouser = {
    println "scriptClouser this:" + this    //代表闭包定义处的类
    println "scriptClouser owner:" + owner  //代表闭包定义处的类或者对象
    println "scriptClouser delegate:" + delegate    //代表任意对象,默认与owner一致
}
scriptClouser.call()

打印输出如下:

scriptClouser this:[email protected]
scriptClouser owner:[email protected]
scriptClouser delegate:[email protected]

this、owner、delegate三者代表同一个对象VariableStudy实例对象

接下来,我们初始化一个内部类Person:

class Person {
    def classClouser = {
        println "classClouser this:" + this
        println "classClouser owner:" + owner
        println "classClouser delegate:" + delegate
    }

    def say() {
        def classClouser = {
            println "methodClouser this:" + this
            println "methodClouser owner:" + owner
            println "methodClouser delegate:" + delegate
        }
        classClouser.call()
    }
}

Person p = new Person()
p.classClouser.call()
p.say()

打印输出如下:

classClouser this:[email protected]
classClouser owner:[email protected]
classClouser delegate:[email protected]
methodClouser this:[email protected]
methodClouser owner:[email protected]
methodClouser delegate:[email protected]

this、owner、delegate三者还是表示同一个对象Person实例对象
现在我们在闭包中再定义一个闭包:

def nestClouser = {
    def innerClouser = {
        println "innerClouser this:" + this
        println "innerClouser owner:" + owner
        println "innerClouser delegate:" + delegate
    }
    innerClouser.call()
}
nestClouser.call()

打印输出如下:

innerClouser this:[email protected]
innerClouser owner:[email protected]
innerClouser delegate:[email protected]

这时候this表示的是类VariableStudy的实例对象,而owner和delegate都表示内部闭包中的实例化对象innerClouser。

那么如何修改delegate和owner不一样呢?

def nestClouser = {
    def innerClouser = {
        println "innerClouser this:" + this
        println "innerClouser owner:" + owner
        println "innerClouser delegate:" + delegate
    }
    innerClouser.delegate = p //修改默认的delegate
    innerClouser.call()
}
nestClouser.call()

打印输出如下:

innerClouser this:[email protected]
innerClouser owner:[email protected]
innerClouser delegate:[email protected]

总结:
1.在类或者方法中定义闭包,那么this、owner、delegate都是一样的(默认不改变delegate);
2.如果在闭包中又嵌套一个闭包,那么this、owner、delegate将不再一样,this将指向闭包定义处外层的实例变量或者类本身(最接近的);而owner和delegate都会指向最近的闭包对象;
3.只有人为的修改delegate,delegate和owner才会不一样(this和owner不可以修改)

闭包的委托策略
class Student {
    String name
    def pretty = {
        "my name is ${name}"
    }
}

class Teacher {
    String name
}

Student stu = new Student(name: "John")
Teacher tea = new Teacher(name: "jack")
println stu.pretty.call()

打印输出如下:

my name is John

接下来我们做如下的修改:

class Student {
    String name
    def pretty = {
        "my name is ${name}"
    }
}

class Teacher {
    String name
}

Student stu = new Student(name: "John")
Teacher tea = new Teacher(name: "jack")
stu.pretty.delegate = tea
stu.pretty.resolveStrategy = Closure.DELEGATE_FIRST
println stu.pretty.call()

打印输出如下:

my name is jack

以上就是闭包的委托策略。

喜欢本篇博客的简友们,就请来一波点赞,您的每一次关注,将成为我前进的动力,谢谢!