• Gradle学习笔记之Groovy


    Gradle是一个基于Apache Ant和Apache Maven概念的项目自动化构建工具。它使用一种基于Groovy的特定领域语言(DSL)来声明项目设置,抛弃了基于XML的各种繁琐配置。Gradle的构建脚本build.gradle和setting.gradle都是可执行的Groovy脚本(不过它们不可以在Groovy运行时环境下运行, 由于上述.gradle文件都需要调用gradle的api运行且后缀不是.groovy). 下面通过与Java对比, 简单介绍小于Gradle相关的Groovy语言知识.

    1. 什么是Groovy

    Groovy是一个基于Java虚拟机的动态语言。这门动态语言拥有类似Python、Ruby和Smalltalk中的一些特性,可以作为Java平台的脚本语言使用。Groovy的语法与Java非常相似,以至于多数的Java代码也是正确的Groovy代码.

    1. Java开发者提供了 现代最流行的编程语言特性,而且学习成本很低。
    2. 支持DSL(Domain Specific Languages领域定义语言)和其它简洁的语法,让你的代码变得易于阅读和维护.
    3. 无缝集成所有已经存在的 Java对象和类库.
    4. 接编译成Java字节码,这样可以在任何使用Java的地方 使用Groovy。

    2. Java VS Groovy

    下面先给出Groovy运行环境下含义相同的Java和Groovy
    代码片, 然后在说明二者的区别

    java

    public class Me {
        private String name; 
        public Me(String name) { this.name = name; }
        public String getName() { return name; }
        public void setName(String name) { this.name = name; }
    }
    
    

    groovy

    class Me {
        String name
        public Me(String name) { this.name = name}
    }
    

    从上面我们可以看到Groovy版本更加简洁,下面给出Groovy相对于Java的特点:

    1. 表达式后面的分号;是可选的;
    2. 每个, 构造器, 方法访问属性默认是public的
    3. 方法体中的最后一个表达式的值被作为返回值, 这意味着return语句是可选的;
    4. Groovy编译器自动加上getter/setter方法, 不需要自己手动添加;
    5. 类的属性可以通过点号.获取与赋值, 底层是通过调用自动生成的getter/setter方法.
    6. Groovy中用==比较两个实例, 底层调用的是equals()方法, 这个操作也可以避免可能的空指针异常.

    3. Groovy 高级特性

    3.1 可选类型定义

    作为动态语言,groovy中所有的变量都是对象,在声明一个变量时,groovy不要求强制类型声明,仅仅要求变量名前使用关键字def, def关键字作为java.lang.Object的一个占位符, 在运行时确定类型.

    //assert用于断言检查 )
    def var = 1
    assert var.class == java.lang.Integer
    var = "bupt"
    assert var.class == java.lang.String
    

    3.2 可选的括号

    在Groovy中如果方法签名需要至少一个参数, 则方法调用可以省略括号.

    
    def callMe(name) {
        new Me(name)
    }
    
    callMe('faith')
    callMe 'faith'
    
    println("we could not live without faith!")
    println "we could not live without faith!"
    
    

    3.3 字符串

    在Groovy中, 有三种不同方式定义字符串. 带单引号'的通常创建等效于Java的String类型; 第二种和Java相同用双引号"包起来, 跨行的字符串用三个双引号包起来""".

    几点说明:

    1. 跟java一样,可以使用+号连接字符串;
    2. Groovy中带双引号的字符串可以插值带变量或者表达式中, 通过$和花括号{}表示, 运行时, Groovy计算表达式并组成字符串.这种字符串在Groovy中叫做GString. 通过下面的例子s4 s5也能看到和单引号的不同.
    def s1 = 'bupt'
    def s2 = "bupt"
    def s3 = """b
    u
    p
    t
    """
    def s4 = "hello "+
    "${s1}"
    def s5 = "hello "+
    '${s1}'
    println s1
    println s2
    println s3
    println s4
    

    输出:

    bupt
    bupt
    b
    u
    p
    t
    hello bupt
    hello ${s1}
    

    3.4 命名参数

    Groovy 中提供了一个减少输入的特性叫做命名参数(Named Parameter)。GroovyBean 可以通过在构造器调用中传递冒号隔开的属性名称和值进行构建。如:

    class Me {
        String name
    }
    
    Me me = new Me(name: "faith")
    println me.name
    me.name = 'bupt'
    println me.name
    

    输出:
    faith
    bupt

    从外部表现上好像是先调用了空构造方法,然后是相应的 setter 方法进行设值。因此,我们所直接想像的应该相当于下列 Java 代码:

    Me me = new Me();
    me.setName("faith");
    

    3.5 闭包

    在介绍闭包前,先来讲几个Groovy中代码块的一些特性。

    3.5.1 代码块

    1. groovy的变量作用域和java相似,代码块内部声明的变量不能被外部访问调用。
    2. 对于Groovy Script, 用def定义的变量对binding.variables不可见。没有def等任何定义的可被binding.variable.参数名所访问。
    3. 对于第一条规则,有个例外,当变量没有def等任何定义时,该变量全局有效.
    4. 代码块可以嵌套,比如try代码块,这和Java是一样的。
    try{
      h = 9
      assert binding.variables.h == 9
    }
    assert h == 9
    assert binding.variables.h == 9
    

    3.5.2 闭包简介

    闭包是类型为groovy.lang.Closure用花括号{}括起来的代码块. 类似于Python的lambda表达式, 闭包可以被赋值给变量, 作为参数传递给方法, 并且像普通方法一样调用.

    看起来,闭包类似于方法,需要定义参数和要执行的语句,它也可以通过名称被调用。然而闭包对象可以作为参数传递. 其次,闭包也可以不命名(当然作为代价,只能在定义闭包时执行一次)

    3.5.3 闭包参数

    1.显示参数闭包:

    闭包的参数声明写在‘->’符号前,调用闭包的的标准写法是:闭包名.call(闭包参数)。

    def toTriple = {n -> n * 3}
    assert toTriple.call( 5 ) == 15
    

    2.隐士参数闭包:

    对于单一存在的参数it可以不用声明,直接使用it,it在Groovy中有着特殊的意义;当且仅当闭包中有且仅有一个参数,且不显示声明,it具有唯一参数引用的作用;如果闭包c是无参数闭包,那么它的标准调用方法是c.call(),它的简洁调用方法是c()。

    c = { it*3 }
    assert c( 'run' ) == 'runrunrun'
      
    def a = 'coffee'
    def c = {
      def b = 'tea'
      a + ' and ' + b 
      }
    assert c() == 'coffee and tea' 
    

    3.闭包隐含参数

    参数 说明
    it 默认的参数名,调用是如果没有传参数,it为null
    this 跟Java一样,是定义闭包所在类的一个引用,不管有多少层闭包嵌套,this指向的都是最上层的类。
    owner 封闭闭包的对象(如果只有一层闭包就是this,如果有多层闭包嵌套就是含有此闭包的上层闭包)
    delegate 缺省值是owner,但是可以改变,后面详说。

    4.闭包中的参数名不能重复,it除外。

    def name= 'cup'
    def c={ name-> println (name) } 
    //a compile error when uncommented:
    //current scope already contains name 'name'
    c= { def d= { 2 * it }; 3 * d(it) }
    assert c(5) == 30
    

    5.闭包是可嵌套的

    def gcd //predefine closure name
    gcd={ m,n-> m%n==0? n: gcd(n,m%n) }
    assert gcd( 28, 35 ) == 7
    

    3.5.4 闭包返回值

    闭包总是会有一个返回值,返回值是闭包的最后一行语句,不论该语句是否冠名return关键字。如果闭包最后一句没有值, 返回 null;

    3.5.5 赋值与调用

    赋值: 闭包赋值给一个变量,和变量与变量间的赋值一致。

    def c
    try{
     def a = 'sugar'
     c = { a } //a closure always returns its only value
    }
    assert c() == 'sugar'
    def d = c //we can also assign the closure to another variable
    assert d() == 'sugar'
    

    调用: 调用闭包的方法等于创建一个闭包实例。对于相同闭包创建出来的不同实例,他们的对象是不同的。

    c = { def e = { 'milk' }; e }
    d = c
    assert c == d
    v1 = c()
    v2 = c()
    assert v1 != v2
    

    3.5.6 闭包委托

    delegate委托的用法
    delegate委托在是一种常用设计模式,但在java中实现相对比较繁琐,groovy直接在GroovyObject中已经实现了delegate模式,所以在groovy中应用delegate很方便。

    下面看一个狗爸爸让老猫帮忙照看他的狗儿子玩游戏的例子:

    class Dog{
        def play = {
          "wang wang!"
        }
        def childmind = {
            println       delegate.play();      
        }
    }
    
    class Cat {
        def play = {"mi mi !"}
    }
    
    def dog = new Dog()
    def cat = new Cat()
    
    dog.childmind()
    
    dog.childmind.delegate  = cat;
    dog.childmind()
    


    3.6 集合

    Groovy支持最常见的两个java集合:
    java.util.Collection和java.util.Map。

    3.6.1 Collection

    //1、定义一个集合
    def collect = ["a","b","c"]
    
    //2、给集合增加元素
    collect.add(1);
    collect << "come on";
    collect[collect.size()] = 100.0
    
    //3、集合索引
    println collect[collect.size()-1]
    println collect
    println collect.size()
    
    //4、负索引
    println collect[-1]      //索引其倒数第1个元素
    println collect[-2]      //索引其倒数第2个元素
    
    //5、集合运算:
    collect=collect+5        //在集合中添加元素5
    println collect[collect.size()-1]
    
    collect=collect-'a'         //在集合中减去元素a(第1个)
    println collect[0]          //现在第1个元素变成b了
    
    //6、往集合中添加另一个集合或删除一个集合:
    collect=collect-collect[0..4]   //把集合中的前5个元素去掉
    println collect[0]   //现在集合中仅有一个元素,即原来的最后一个元素
    println collect[-1]  //也可以用负索引,证明最后一个元素就是第一个元素
    

    3.6.2 Map

    Map是“键-值”对的集合,在groovy中,键不一定是String,可以是任何对象(实际上Groovy中的Map就是java.util.LinkedHashMap)。

    //1、定义一个Map:
    def map = ['name':'john','age':14,'sex':'boy']
    println map
    
    //2、添加项:
    map = map+['weight':25]       //添加john的体重
    map.put('length',1.27)      //添加john的身高
    map.father='Keller'         //添加john的父亲
    println map
    
    //3、两种方式检索值:
    println map['father']       //通过key作为下标索引
    println map.length          //通过key作为成员名索引
    

    闭包中最常见的应用是对集合进行迭代,下面定义了3个闭包对map进行了迭代:

    def map = ['name':'john','age':14,'sex':'boy']
    map.each(
            {key,value->     // key,value两个参数用于接受每个元素的键/值
        println "$key:$value"})
    
    map.each{println it}     //it是一个关键字,代表map集合的每个元素
    map.each({ println it.getKey()+"-->"+it.getValue()})
    

    打印如下:

    name:john
    age:14
    sex:boy
    name=john
    age=14
    sex=boy
    name-->john
    age-->14
    sex-->boy
    




    参考:

    1. Groovy基础——Closure(闭包)详解
    2. Unmi 学习 Groovy 之命名参数
    3. Groovy语言学习:groovy语言简介及基本语法
    4. <gradle实战>
  • 相关阅读:
    百度高级搜索技巧
    JRebel插件使用详解
    css3自适应布局单位vw,vh详解
    vue的MVVM原理
    JS实现全屏和退出全屏
    设置不定宽高的元素垂直水平居中
    微信小程序启动更新机制
    了解MVVM原理
    xss攻击和csrf攻击的定义及区别
    跨站脚本漏洞(XSS)基础讲解
  • 原文地址:https://www.cnblogs.com/nowgood/p/Gradle-xue-xi-bi-ji-zhiGroovy.html
Copyright © 2020-2023  润新知