Gradle系列知识(一)—— Groovy基础变量和闭包

一、变量与字符串

java 语法在Groovy文件中可以用。

1、强类型
强类型直接用变量类型申明变量
弱类型可以用def 申明变量 ,编译器自动识别类型,弱类型用之前必须初始化,强类型可以不初始化。

int x = 1
char y = 'a'

2、弱类型
弱类型用def关键字定义

def x = 1
def y = 'A'

弱类型的定义必须初始化,不然编译器不知该怎么初始化该变量。

弱类型可以随意进行类型转换,只要是能转的类型,比如将char转为String。

3.String的定义的3种方式

def name1 = 'abc'
def name2 = "defg"
def name3 = '''hijkml'''

第一种单引号的用法跟java没有任何区别
第二种双引号,可以用$符号进行字符串拼接,也可以进行运算,如

def sum = "${3+2}"
println("sum 的值是$sum")

输出结果

sum 的值是5

第三种三引号可以完整原样得将用户输入的内容显示,比如在单引号中需要用“\n”来实现换行效果,三引号中直接用回车即可。

groovy中的字符串还可以做减法

def name1 = "abc"
def name2 = "abcdefg"
println(name2-name1)

输出结果是

defg

String还有跟Java类似的一系列的API,大家都可以自己去尝试下

二、闭包的基础用法

匿名内联函数,也称为一个闭包。本质上,闭包是将函数内部和函数外部连接起来的桥梁。
简单点讲,可以将闭包看作是将函数申明为变量,这个变量可以传递,也可以直接调用,从而执行闭包里面的代码块

def closure = {//闭包的申明方式
    println("我是闭包")
}

closure()//闭包的调用方式1
println("______________________")
closure.call()//闭包的调用方式2

以上
输出结果:

我是闭包
______________________
我是闭包

以上是无参数的闭包,现在我们看看有参数的闭包

def closure = {
    String name,int age->//参数和函数体之间用->隔开
        println("我是有参的闭包,我的名字是$name, 我的年龄是 $age")
}

closure.call("BB",18)

输出结果是

我是有参的闭包,我的名字是BB, 我的年龄是 18

上面我们看到了无参和有参的闭包,现在我们看看默认参数的闭包

def closure = {
        println("我是默认参数的闭包,我的名字是$it")//无参的闭包中都用一个默认的参数it
}

closure.call("MB")

闭包也可以有返回值,跟函数的返回值一样,在函数体的最后通过return返回,在调用的时候接收 ,这里就举例了。

闭包作为内联函数的使用

int a = fab(5)
int fab(int num){
    int result = 1
    1.upto(num,{number->result *= number})
    return result
}

println(a)

如果是第一次接触闭包,看到上面的代码可能会有点懵,接下来我们会一步步解释。
upto是int提供的函数,参数有2个,第一个是num,第二个是闭包,这里相当于申明了一个匿名函数,只是申明,这个闭包的调用在upto函数体里面。我们再看看upto函数

 public static void upto(Number self, Number to, @ClosureParams(FirstParam.class) Closure closure) {
        int self1 = self.intValue();
        int to1 = to.intValue();
        if (self1 > to1) {
            throw new GroovyRuntimeException("The argument (" + to + ") to upto() cannot be less than the value (" + self + ") it's called on.");
        } else {
            for(int i = self1; i <= to1; ++i) {
                closure.call(i);
            }

        }
    }

我们看到upto这里接收可3个参数,第一个参数self是前面调用的1,第二个参数才是我们传入的num,第三个参数是我们传入的闭包,可以看到我们传入的闭包,在for循环里面调用了,并传入了参数i。看for循环是将传入的参数self由1逐渐变大,也就是这里调用upto实现的效果就是用1*2*3*4*5,输出结果是

120

同理这里int的api还有downto,可将传入参数由大变小进行运算

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

让我们先看看这样一份代码

def closure1 = {
        println("我是 closure1  this       ="+this)
        println("我是 closure1  owner      ="+owner)
        println("我是 closure1  delegate   ="+delegate)
    def closure2 ={
        println("我是 closure2  this       ="+this)
        println("我是 closure2  owner      ="+owner)
        println("我是 closure2  delegate   ="+delegate)
        def closure3 ={
            println("我是 closure3  this       ="+this)
            println("我是 closure3  owner      ="+owner)
            println("我是 closure3  delegate   ="+delegate)
        }
        closure3.call()
    }
    closure2.call()
}

closure1.call()

看看运行结果

我是 closure1  this       =TestString@38089a5a
我是 closure1  owner      =TestString@38089a5a
我是 closure1  delegate   =TestString@38089a5a
我是 closure2  this       =TestString@38089a5a
我是 closure2  owner      =TestString$_run_closure1@54e7df6a
我是 closure2  delegate   =TestString$_run_closure1@54e7df6a
我是 closure3  this       =TestString@38089a5a
我是 closure3  owner      =TestString$_run_closure1$_closure2@77128536
我是 closure3  delegate   =TestString$_run_closure1$_closure2@77128536
  • this是带边闭包定义处的类,即如果是闭包里面嵌套闭包,内层闭包的this只能代表内层。这个跟java 中的this和内部类的机制差不多,应该不难理解。
  • owner和delegate现在看上去没有什么区别,都代表当前闭包的上一个闭包

我们再在上面定义closure3 的下面加两行代码,将字符串“abc”赋值给closure3的delegate和owner

closure3.owner = "abc"
closure3.delegate = "abc"

在看看打印结果

我是 closure3  owner      =TestString$_run_closure1$_closure2@6b88ca8c
我是 closure3  delegate   =abc

owner 和delegate 的区别就是delegate 能手动修改赋值成任何对象,而owner 则不能。

那么delegate 这么设计有什么用呢?
让我们看看下面一份代码

class Worker{
   String name
}

class Student{
    String name;
    def introducte = {
        println("我是 $name")
    }
    String toString(){
        introducte.call()
    }
}

def student = new Student(name:"小强")
def worker = new Worker(name:"Michael")
/*student.introducte.delegate = worker
student.introducte.resolveStrategy = Closure.DELEGATE_FIRST*/  
student.introducte.call()

输出结果为

我是 小强

这里应该没什么疑问,name的取值是student 的。如果我们把注释的两行代码放开,看看输出结果

我是 Michael

通过解开注释的两行代码,我们设置委托策略delegate 优先,闭包就会从它现有delegate 中去找传入参数,执行程序,也就直接从worker 中取name值。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值