美文网首页Android
Gradle学习1——Groovy基本介绍

Gradle学习1——Groovy基本介绍

作者: sososeen09 | 来源:发表于2017-10-14 16:51 被阅读184次

    学习Gradle,前前后后总结了一些内容,然后整理出了一个系列,共计10篇文章,与大家分享:

    1. Groovy基本介绍
    2. 开始使用Gradle
    3. 自定义属性
    4. 深入了解Task和构建生命周期
    5. Gradle增量式构建
    6. 挂接到构建生命周期
    7. 编写和使用自定义Task
    8. 依赖管理
    9. 多项目构建
    10. 自定义Gradle插件

    学习本系列前可以下载相关的github项目gradleLearnDemo
    地址:https://github.com/sososeen09/gradleLearnDemo

    0 前言

    Gradle脚本使用的是Groovy语言,Groovy也是基于JVM的一种动态语言,基于Java并扩展了Java语言。Groovy会使写Java程序就要写脚本一样简单,写完就可以执行,所以看起来也像是一门脚本语言。Groovy内部会把代码编译为Java class文件然后启动虚拟机来执行,这些过程,我们开发人员是不用管的。

    Gradle是一种DSL,也即是 Domain Specific Language 领域特定语言。说白了DSL就是一种行话,这个语言在Gradle中可以识别,在其它地方就用不了了。

    学习Gradle,我们不必要精通Groovy语言,但还是需要了解一些Groovy的基本知识,比如def关键字、返回语句、字符串、集合、闭包等。下面,我们就来简单介绍一下。

    1 Groovy代码的执行

    前面我们说了,Groovy很像是一门脚本语言,我们来看一下怎么回事。
    创建一个HelloGroovy.groovy文件,里面就一行代码

    println 'hello groovy!'
    

    然后执行命令groovy HelloGroovy.groovy,得到结果

    hello groovy!
    

    是不是很简单,很像脚本语言。

    2 Groovy中的字符串

    Groovy 对字符串支持相当强大,可以使用多种字符串,包括单引号、双引号、三引号。

    String str='hello groovy!'
    
    String getStr(){
        'hello groovy!'
    }
    
    String str1='hello'
    String str2=' groovy!'
    println 'hello groovy!'
    println "hello groovy!"
    println "$str"
    println getStr()
    println "${str1+str2}"
    println 'hello $str2'  //单引号,直接打印内容
    

    使用单引号会直接打印字符串的内容,不会对美元$符号的内容进行转义。使用双引号的功能更加强大,字符串中使用美元符$后面可以跟字符串变量,如"$str",也可以跟表达式如 "${str1+str2}",如果跟表达式,记得要用{}括起来。

    三引号用的比较少,可以支持字符串内容换行,我们了解一下就行。

    println ''' aa
    bb
    
    cc
    '''
    

    我们在getStr()方法中并没有使用return语句,这是因为Groovy默认是把最后一行的执行结果进行返回。如果你需要返回的结果正好是最后一行,就可以省略return。

    另外,在Groovy中,语句的最后的“;”号是可以省略的。还有一点就是Groovy中在调用函数的时候可以不加括号,比如,println ("hello")println "hello" 的意思是一样的

    3 def关键字

    def关键字很像是Java中的Object,在定义变量或者方法的时候使用def,如果没有指定具体的参数类型。在运行阶段Groovy会自动判断参数类型。

    def a = 1, b = 2
    def str = "hello"
    println a + b
    println str
    

    实际上我们在定义变量的时候是可以省略def的,如

    a = 1
    b = 2
    str = "hello"
    

    但是,最好还是加上def,这是一种好的实践。
    你还可以在定义变量的时候,在def后面再加上具体的参数类型,如

    def int a = 1
    def String str = "hello"
    

    使用def定义方法的返回值类型,可以返回任意类型。如果指定了具体的返回值类型,就要正确的返回,否则会报错。

    4 集合

    Groovy的基本类型与Java一样。对于集合类型的数据,List的具体实现是ArrayList。Map集合的具体实现是LinkedHashMap。

    4.1 List

    下面我们来简单了解一下如果使用。List使用一个 []中括号来括起来来表示的。

    //定义一个List
    def lists=['groovy','gradle','android']
    
    //打印集合size
    println lists.size
    
    //打印集合中的数据
    lists.each{
        list->println list
    }
    

    取出集合中的数据直接用索引就可以了。比如:

    assert lists[0]=='groovy'
    

    对于集合中变量的存储,我们是不需要担心数组越界的,如果索引超过当前长度,List会自动在该索引中添加元素。比如

    lists[100]=100
    println lists.size
    println lists[99]
    

    打印结果,会发现集合的size变为101。index为99的集合数据为null。

    4.2 Map

    Map的表示就是用中括号[]括起来的 key:value形式。

    def map=["key1":"hello","key2":"groovy","key3":true]
    println map.size()
    
    map.forEach{
        key,value->
        println "$key :$value"
    }
    

    结果是:

    3
    key1 :hello
    key2 :groovy
    key3 :true
    

    获取Map的元素

    println map.'key1'
    println map['key1']
    

    添加元素

    map.'key4'='android'
    println map['key4']
    

    5 Groovy的类

    Groovy中的类与Java中的类的写法类似,但是要更简洁一些。
    我们在Hello.groovy文件中写一个HelloWorld类。

    class HelloWorld{
        String msg='hello world'
        
        HelloWorld(){
            
        }
    
        HelloWorld(String msg){
            this.msg=msg
        }
    
        void sayHello(){
            println msg
        }
    }
    
    def say={
        new HelloWorld('hello').sayHello()
    }
    
    def getMsg={
        new HelloWorld().msg
    }
    
    say()
    println getMsg()
    
    

    调用groovy Hello.groovy 命令执行该脚本,结果如下:

    hello
    hello world
    

    当然了,我们也可以写一个单独的HelloWorld类,带上包名,然后在其它地方导包使用,就像Java那样。有关于Groovy类的使用,我们后面还会讲到,这里就不赘述了。
    总结一下Groovy的类相比Java的一些不同,或者说是优化的一些地方:

    • 表达式后面的分号是可选的
    • 每个类、构造方法和方法默认是public的
    • 在Groovy中,方法体中的最后一个表达式的值会被作为返回值。这意味着return语句是可选的
    • Groovy编译器自动加上getter/setter方法,所以不需要自己去书写
    • 类的属性可以通过点号来获取,看起来好像它们在Java中是public的,在底层Groovy调用的是自动生成的getter/setter方法。

    6 闭包

    闭包Closure,在Groovy中是很重要的一种数据类型。闭包实际上就是一段代码块,需要用{}包括起来。前面我们在讲解一些例子的时候已经用到了闭包,我们再来看一下闭包的结构。

    //定义一个闭包 ,记得要用{}包裹起来
    def aClosure={
        int a,int b-> //-> 箭头前面代表的是参数,后面是执行语句
        a+b  //返回值
    }
    
    println aClosure(1,2)
    

    结果为 3。

    闭包的参数类型也可以不指定,在运行期有Groovy自动推断,比如下面这个例子,执行起来也是没有问题的

    def bClosure={
         a,b->
        a+b
    }
    
    println bClosure(1,2)
    

    闭包也可以没有参数
    如:

    def aa={
        println "this is a Closure"
    }
    aa()
    

    总结一下,闭包的类型有

    1. def closureNama ={params -> code} 
    2. def closureName= {code} 没有参数的时候就没有箭头 ->
    

    闭包的调用有两种方式

    1. 闭包对象.call(参数)
    2. 闭包对象(参数)
    
    如
    aClosure(1,2)
    aClosure.call(1,2)
    

    需要注意一点,闭包如果没有参数的话,其隐含了一个参数是 it
    和this的作用类似,代表的是传入闭包的参数。比如:

    def sayHello={"hello ${it}"}
    println sayHello("Jim")
    
    等同于
    def sayHello={it->"hello ${it}"}
    

    当然了,如果闭包显示的指明了无参数,则在调用闭包的时候不能传参数,否则会报错。如

    def noParams={->println "noParams"}
    noParams();
    //下面的代码执行会报错
    //noParams(1)
    

    闭包返回值
    闭包总是会返回一个值。返回值是闭包的最后一条语句的值(如果没有显式的return语句),或者是可执行的return 语句的值。如果闭包的最后一条语句没有值就返回null。如之前举得Hello.groovy中的例子:

    def getMsg={
        new HelloWorld().msg
    }
    

    闭包作为方法参数
    闭包也可以作为方法参数,如:

    int increment(Closure closure,int count){
        closure()+count
    }
    //断言,如果为true就正常执行,如果为false,就会报错
    assert increment({1+1},1)==3
    

    闭包委托
    闭包代码是在委托的闭包上执行。默认的,这个委托就是闭包的所有者。比如你在Groovy脚本中定义了一个闭包,那么所有者就是一个groovy.lang.Script实例。闭包的隐式变量delegate 允许你重新定义默认的所有者。

    例如:

    class Test {
        def x = 30
        def y = 40
    
        def run() {
            def data = [ x: 10, y: 20 ]
            def cl = { 
                y = x + y 
            }
            cl.delegate = data
            cl.resolveStrategy = Closure.DELEGATE_FIRST
            cl()
            assert x == 30
            assert y == 40
            assert data == [x:10, y:30]
        }
    }
    
    new Test().run()
    

    上面例子中闭包c1的委托变为data,闭包的resolveStrategy在默认情况下是OWNER_FIRST,即它会先查找闭包的owner(在本例中指的就是Test对象本身),如果owner存在,则在owner上执行闭包中的代码。这里我们将其设置成了DELEGATE_FIRST,即该闭包会首先查找delegate(本例中即data),如果找不到再去找owner。resolveStrategy还有其它的一些情况,具体的可以查看文档中的例子,相信当你看到这些例子后,会对闭包委托有一个清晰的认识。

    7 总结

    限于篇幅和本系列的主题,本文简单介绍了Groovy的一些语法和数据结构,这对于学习Gradle会有一些帮助。在后面Gradle的学习过程中,如果对Groovy的一些Api不熟悉可以查看Groovy的Api文档,我们没必要死记硬背这个Api,掌握学习的方法更加重要,对吗?

    下一篇,我们就正式进入Gradle部分的学习了。

    参考

    相关文章

      网友评论

        本文标题:Gradle学习1——Groovy基本介绍

        本文链接:https://www.haomeiwen.com/subject/vbcaextx.html