Android开发Android开发Android技术知识

Groovy基础

2018-06-30  本文已影响12人  XiMiMax

<<Android Gradle权威指南》阅读笔记——Groovy基础

​ 本文讲述Groovy 基础Groovy是基于JVM虚拟机的一种动态语言,又在此基础上增加了很多动态类型和灵活特性,比如支持闭包,支持DSL,可以说它是一门非常灵活的动态脚本语言。

​ 每个Gradlebuild脚本文件都是Groovy脚本文件你可以在里面写任何符合Groovy语法的代码,比如定义类,声明函数,定义变量等;而Groovy又完全兼容Java,这就意味着你可以在build脚本文件里写任何的Java代码。


1. 字符串

Groovy中,单引号和双引号都可以定义一个字符串常量(Java里单引号定义一个字符),不同的是单引号标记的是纯粹的字符串常量,而不是对字符串里表达式做运算,单引号没有运算能力,双引号可以:

task printStringClass << {
     def str1 = '单引号'
     def str2 = "双引号"
    ​
     println "单引号定义的字符串类型:"+str1.getClass().name
     println "双引号定义的字符串类型:"+str2.getClass().name
    }
./gradlew printStringClass 输出
    Task :printStringClass
    单引号定义的字符串类型:java.lang.String
    双引号定义的字符串类型:java.lang.String</pre>
task printStringVar << {
     def name = "张三"
    ​
     println '单引号的变量计算:${name}'
     println "双引号的变量计算:${name}"
    }</pre>
./gradlew printStringVar 输出
 Task :printStringVar
    单引号的变量计算:${name}
    双引号的变量计算:张三

2. 集合

Groovy完全兼容了Java的集合,并进行了扩展,使操作变得更容易。

task printList << {
     def numList = [1,2,3,4,5,6];
     println numList.getClass().name //输出时可以看出 numList 是一个 ArrayList
    ​
     println numList[1]//访问第二个元素 下标索引 下标从 0 开始
     println numList[-1]//访问最后一个元素 负下标 
     println numList[-2]//访问倒数第二个元素 负下标
     println numList[1..3]//访问第二个到第四个元素 范围索引 由”.."分开
    ​
     numList.each{//迭代操作
     println it //it 正在迭代的元素,这里涉及闭包的知识,下文会讲解
     }
    }
./gradlew printList 输出
Task :printList
    java.util.ArrayList
    2
    6
    5
    [2, 3, 4]
    1
    2
    3
    4
    5
    6
task printMap << {
     def mapl = ['width':1920,'height':1080]
     println mapl.getClass().name //输出可以看出mapl是一个LinkedHashMap
    ​
     //访问可以采用map[key]或者map.key两种方式
     println mapl['width']
     println mapl.height
    ​
     mapl.each{//迭代操作
     println "Key:${it.key},Value:${it.value}"//此处的it是一个Map.Entry实例
     }
    }
./gradlew printMap 输出
 Task :printMap
    java.util.LinkedHashMap
    1920
    1080
    Key:width,Value:1920
    Key:height,Value:1080

关于集合的更多方法后续会补充,有兴趣的可以自行先了解

3. 方法

通过了解Groovy方法和Java方法的不同,更利于我们明白Gradle脚本里的代码

task invokeMethod << {
     //这两种调用方式结果一直,但第二种更简洁
     methodl (1,2)
     methodl 1,2
    }
    ​
    def methodl(int a, int b){
     println a+b
    }
./gradlew invokeMethod 输出
 Task :invokeMethod
    3
    3
task printMethodReturn << {
     def add1 = method2 1,2
     def add2 = method2 5,3
     println "add1:${add1},add2:${add2}"
    }
    ​
    def method2(int a,int b){
     if(a>b){
       a //执行到此处 返回a
     }else{
       b //执行到此处 返回b
     }
    }
./gradlew printMethodReturn 输出
 Task :printMethodReturn
    add1:2,add2:5
    //最初的写法
    numList.each({println it})
    ​
    //经过格式化
    numList.each({
       println it
    })
    ​
    //Groovy中方法的最后一个参数为闭包,可以放到外面
    numList.each(){
       println it
    }
    ​
    //去掉方法的括号
    numList.each{
       println it
    }

4. JavaBean

JavaBean中繁琐的getter/setterGroovy中得到了很大改善

task helloJavaBean << {
   Person p = new Person()
​
   println "名字是:${p.name}"//此时name为赋值,返回null
   p.name = 'tom'
   println "名字是:${p.name}"//已赋值,返回tom
   println "年龄是:${p.age}"//未定义成员变量时,通过getAge()方法也可获取age,但不能修改值
}
​
class Person{
   private String name
   public int getAge(){
     12
 }
}

./gradlew helloJavaBean 输出

 Task :helloJavaBean
名字是:null
名字是:tom
年龄是:12

5. 闭包

闭包是Groovy的一个非常重要的特性,可以说他是DSL的基础。

task helloClosure << {
 //使用自定义闭包
   customEach {
     println it
   }

​
 //多个参数
   eachMap {k,v ->
     println "${k} is ${v}"
    }
}
​
def customEach(closure){//唯一参数,用于接收一个闭包(代码块)
   //模拟一个集合,开始迭代
   def numList = [1,2,3]
   numList.each{
     closure(it)
   }
}
​
def eachMap(closure){//此处的闭包传递两个参数k v
   def mapl = ["name":"tom","age":18]
   mapl.each{
     closure(it.key,it.value)
   }
}

./gradlew helloClosure 输出

 Task :helloClosure
1
2
3
name is tom
age is 18

Groovy闭包的强大之处在于它支持闭包方法的委托。Groovy的闭包有thisObject,owner,delegate三个属性,当你在闭包内调用方法时,由它们来确定使用哪个对象来处理。默认情况下delegateowner是相等的,但是delegate是可以被修改的,这个功能是非常强大的,Gradle中的很多功能都是通过修改delegate实现的。

task helloDelegate << {
   new Delegate().test{
     println "thisObject:${thisObject.getClass()}" //thisObject优先级最高
     println "owner:${owner.getClass()}"//owner优先级次之
     println "delegate:${delegate.getClass()}"
     //delegate优先级最低,但是owner==delegate
     //闭包内方法的执行顺序:thisObject>owner>delegate
     method3()
     it.method3()
   }
}
​
def method3(){
   println "Context this:${this.getClass()} in root"
   println "method3 in Delegate"
}
​
class Delegate{
   def method3(){
     println "Delegate this:${this.getClass()} in Delegate"
     println "method3 in Delegate"
   }
​
   def test(Closure<Delegate> closure){
     closure(this)
   }
}

./gradlew helloDelegate 输出

 Task :helloDelegate
thisObject:class build_edqlj0scrowqqm8jgfgirxcz4
owner:class build_edqlj0scrowqqm8jgfgirxcz4$_run_closure10
delegate:class build_edqlj0scrowqqm8jgfgirxcz4$_run_closure10
Context this:class build_edqlj0scrowqqm8jgfgirxcz4 in root
method3 in Delegate
Delegate this:class Delegate in Delegate
method3 in Delegate

DSL中,比如Gradle,我们会指定delegate为当前的it,这样我们在闭包内就可以对该it进行配置,或调用其方法。

task configClosures << {
   man {//在闭包类直接对Man实例配置
     manName = "tom"
     manAge = 19
     dumpMan()
   }
}
​
class Man{
   String manName
   int manAge
​
   def dumpMan(){
     println "name is ${manName},age is ${manAge}"
   }
}
​
def man(Closure<Person> closure){
   Man p = new Man();
   //设置委托对象为当前创建的Man实例
   closure.delegate = p 
   //委托模式优先
   closure.setResolveStrategy(Closure.DELEGATE_FIRST);
   closure(p)
}

./gradlew configClosures 输出

 Task :configClosures
name is tom,age is 19

6. DSL

DSL(Domain Specific Language)——领域特定语言(专门关注某一领域的语言)

Gradle就是一门DSL,它基于Groovy专门解决自动化构建的DSL

到这Groovy基础就简单介绍完了,后续我们再学习新的Gradle知识,欢迎持续关注

原文链接 更多类容

上一篇 下一篇

猜你喜欢

热点阅读