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实战>

Gradle学习笔记之Groovy的更多相关文章

  1. gradle学习笔记

    一直想着花时间学习下gradle,今天有空.入门一下.参考:极客学院gradle使用指南,官方文档:gradle-2.12/docs/userguide/installation.html,以及百度阅 ...

  2. Android Gradle 学习笔记(四):Gradle 构建脚本

    本节我们从整体的角度来介绍一下Gradle. 一.setting.gradle 在Gradle中,定义了一个设置文件,用于初始化以及工程树的配置.设置文件的默认的名字就是setting.gradle, ...

  3. gradle学习笔记(1)

    1. 安装     (1) 下载最新gradle压缩包,解压到某处.地址是:Gradle web site:     (2) 添加环境变量:             1) 变量名:GRADLE_HOM ...

  4. Android Gradle 学习笔记(一):Gradle 入门

    官网地址:https://gradle.org/. 一.配置 Gradle 环境 安装Gradle之前必须要配置好Java环境,要求JDK 6 以上,并且在环境变量配置好JAVA_HOME.查看Jav ...

  5. Gradle学习笔记(1)创建简单的Java项目

      Gradle是一个基于Apache Ant和Apache Maven概念的项目自动化构建工具.它使用一种基于Groovy的特定领域语言(DSL)来声明项目设置,抛弃了基于XML的各种繁琐配置.当前 ...

  6. Android Gradle 学习笔记(五):Gradle 任务 Task

    在之前的学习中,我们了解到Gradle的构建工作都是由Task组合完成的.本节我们就来介绍一下 Task - 任务. 一.多种方式创建任务 在Gradle中,我们可以有很多种方式来创建任务.为什么有这 ...

  7. Android Gradle 学习笔记(六):Gradle 插件

    Gradle 本身提供了一些基本的概念和整体核心的框架,其他用于描述真实使用场景的都可以通过插件扩展的方式来实现.这样就可以通过抽象的方式提供一个核心的框架,其他具体的功能和业务都通过插件扩展的方式来 ...

  8. Android Gradle 学习笔记(七):Android Gradle 插件

    我们知道Android Gradle其实就是一个Gradle的一个第三方插件,它是由Google的Android团队开发的,基于Gradle构建的,和Android Studio完美搭配.相比于旧的构 ...

  9. Android Gradle 学习笔记(三):Gradle 日志

    在第一节,我们使用到了gradle -q hello命令行来运行Hello World,并对Hello World进行了简单的分析,了解到 gradle -q hello 的意思是要执行的build. ...

随机推荐

  1. 又是一个MVP+RxJava+Retrofit的干货集中营

    欢迎访问我的个人博客 ,未经允许不得转发 前言 今天想要与大家一起分享的是近一个星期内开发的一个新app--干货集中营客户端,其实网上已经有许多类似的项目,代码家也在他的干货集中营中推荐了几款优秀的作 ...

  2. 学生成绩管理C++版

    [标题]学生成绩管理的设计与实现 [开发语言]C++ [主要技术]STL [概要设计]类名:student 类成员:No.Name.Math.Eng.Chn.Cpro.Sum 成员函数:getname ...

  3. Bash Scripting Learn Notes

    References: [1] http://www.tldp.org/LDP/Bash-Beginners-Guide/html/ 1. Executing programs from a scri ...

  4. wiringPi安装

    wiringPi安装   更新软件,输入以下指令:   sudo apt-get update   sudo apt-get upgrade   通过GIT获得wiringPi的源代码   git c ...

  5. nrm是什么?以及nrm的安装与命令

    nrm的作用与安装使用 一.nrm是什么? 这是官方的原话: 开发的npm registry 管理工具 nrm, 能够查看和切换当前使用的registry, 最近NPM经常 down 掉, 这个还是很 ...

  6. 全局精确流量调度新思路-HttpDNS服务详解

    但凡使用域名来给用户提供服务的互联网企业,都或多或少地无法避免在有中国特色的互联网环境中遭遇到各种域名被缓存.用户跨网访问缓慢等问题.那么对于腾讯这样的域名数量在10万级别的互联网公司来讲,域名解析异 ...

  7. Libevent源码分析—event_set()

    初始化完event_base后,下面要初始化event,通过调用event_set()实现 .相关源码位于event.c event_set() void event_set(struct event ...

  8. HTML5资源教程

    新款CSS3按钮组合 5组可爱CSS3按钮 Leave a reply 之前我分享过一些时尚的CSS3动画按钮,比如CSS3渲染Checkbox实现3D开关切换按钮.纯CSS3 3D按钮 按钮酷似牛奶 ...

  9. Windows 修改电脑属性(一)

    修改电脑属性里的注册信息 修改电脑属性的注册信息 运行注册表的方法:开始→运行→regedit→确定 1.CPU型号可以注册表编辑器中定位到下面的位置: HKEY_LOCAL_MACHINE\HARD ...

  10. Swift 了解(1)

    Apple取消了oc的指针以及其他不安全的访问的使用,舍弃的smalltalk语法,全面改为点语法,提供了类似java的命名空间 范型 重载: 首先我们了解一下Swift这门语言.Swift就像C语言 ...