原文发于微信公众号 jzman-blog,欢迎关注交流。

上一篇学习了 Gradle 的入门知识,Gradle 基于 Groovy,今天学习一下 Groovy 的基础知识,Groovy 是基于 JVM 虚拟机的一种动态语言,语法与 Java 语法类似,Groovy 完全兼容 Java,每个 Gradle 文件都是一个 Groovy 脚本文件,Gradle 文件基于 Groovy 语法,而 Groovy 又兼容 Java,故可以在 Gradle 文件中写 Java 代码,在此基础上增加了很多新特性,如支持闭包、DSL等,可以说 Groovy 是一门非常灵活的动态脚本语言,阅读本文之前可以先阅读下面这篇文章:

下面针对 Gradle 来学习一下 Groovy 的一些基础知识。

  1. 字符串
  2. 集合
  3. 方法
  4. JavaBean
  5. 关于闭包

字符串

说一个 Groovy 的特性,在 Groovy 中分号不是必须的,其单引号是双引号都定义的是一个字符串常量,不同之处是单引号是纯粹的字符串常量,不会对该字符串里面的表达式做运算,而使用双引号定义的字符串常量可以使用合法表达式做相关运算,测试代码如下:

task stringTest{
//使用def关键字定义变量,
def str1 = "双引号"
def str2 = '单引号' println "双引号定义的字符串:"+str1
println "双引号定义的字符串:"+str1.class
println "单引号定义的字符串:"+str2 //变量动态变化
str1 = true;
println "双引号定义的字符串:"+str1.class //使用$运算符
println "双引号定义的字符串:${str1}"
//只有一个变量的时候可以省去中括号
println "双引号定义的字符串:$str1" //单引号定义的字符串不能使用表达式进行运算
println '单引号定义的字符串:$str2'
}

下面是执行结果,参考如下:

PS E:\Gradle\study\Groovy> gradle stringTest

> Configure project :
双引号定义的字符串:双引号
双引号定义的字符串:class java.lang.String
单引号定义的字符串:单引号
双引号定义的字符串:class java.lang.Boolean
双引号定义的字符串:true
双引号定义的字符串:true
单引号定义的字符串:$str2 BUILD SUCCESSFUL in 1s

集合

Groovy 中也有集合的概念,主要看一下常用的 List、Map,下面将对 List 和 Map 常用操作进行介绍。

那么如何在 Groovy 中定义 List 呢,Groovy 中的 List 的定义方式类似于 Java 中的数组,具体操作参考下面代码:

task list{
//定义List
def list = [1,2,3,4,5,6];
def weekList = ['星期一','星期二','星期三','星期四','星期五','星期六','星期日'];
println "list的类型:"+list.class
println "weekList的类型:"+weekList.class //访问集合里面的元素
println '第一个元素:'+list[0]//访问第一个元素
println '第二个元素:'+list[1]//访问第二个元素,以此类推 println '最后一个元素:'+list[-1]//访问最后一个元素
println '倒数第二个元素:'+list[-2]//访问倒数第二个元素,以此类推
println '某个范围内元素:'+list[2..4]//访问某个范围内元素,以此类推 //使用each遍历集合中的元素
weekList.each{
//使用it作为迭代的元素变量,不能写错喔
println it
}
}

下面是上述代码的执行结果,参考如下:

PS E:\Gradle\study\Groovy\ListMap> gradle list

> Configure project :
list的类型:class java.util.ArrayList
weekList的类型:class java.util.ArrayList
第一个元素:1
第二个元素:2
最后一个元素:6
倒数第二个元素:5
某个范围内元素:[3, 4, 5]
星期一
星期二
星期三
星期四
星期五
星期六
星期日 BUILD SUCCESSFUL in 2s

那么如何在 Groovy 中定义 Map 呢,Groovy 中的 Map 当然也是键值对,具体定义及操作参考下面代码:

task map{

	//定义Map
def map = ['name':'Groovy', 'age':10];
println "map的类型:"+map.getClass().name; //访问Map里面的元素
println map.name;
println map['name']; //遍历Map中的元素
map.each{
println "Key:${it.key},value:${it.value}"
}
}

下面是上述代码的执行结果,参考如下:

PS E:\Gradle\study\Groovy\ListMap> gradle map

> Configure project :
map的类型:java.util.LinkedHashMap
Groovy
Groovy
Key:name,value:Groovy
Key:age,value:10 BUILD SUCCESSFUL in 2s

关于 Groovy 的集合就了解这么多。

方法

Groovy 中的方法和 Java 中的方法类似,只是写法上更加灵活,Groovy 中 return 不是必须的,在不写 return 的时候,Groovy 会将最后一句代码作为该方法的返回值。代码块指的是一段被花括号包围的代码,Groovy 中可将代码块作为一个参数进行传递,可以参考前面关于集合的遍历部分,参考代码如下:

task method{
//方法调用
methodA(1, 2)
methodA 1, 2 //获取方法返回的结果
def a = methodA 10, 20
println '获取方法返回的结果:'+a //代码块作为参数传递
def list = [1,2,3,4,5];
list.each(
//闭包参数
{
// println it
}
) //Groovy规定,如果方法的最后一个参数是闭包,可以直接放到方法外面
list.each(){
// println it
} //简写方式
list.each{
println it
}
} //方法的定义
def methodA(int a, int b){
println a + b
//Groovy中return语句不是必须的,默认将最后一句代码的结果作为返回值
a + b
}

下面是上述代码参考如下:

PS E:\Gradle\study\Groovy\Method> gradle method

> Configure project :
3
3
30
获取方法返回的结果:30
1
2
3
4
5 BUILD SUCCESSFUL in 2s

JavaBean

Groovy 中的 JavaBean 相较 Java 中的比较灵活,可以直接使用 javaBean.属性的方式获取和修改 JavaBean 的属性值,无需使用相应的 Getter、Setter 方法,直接看代码:

task javaBean{
//Groovy中定义JavaBean
Student student = new Student()
student.name = "Groovy"
student.age = 10 student.setName("Gradle")
println "名字是:"+student.name
//不能调用Getter方法获取值
// println "名字是:"+student.getName
println "年龄是:${student.age}"
println "分数是:"+student.score
} class Student{
private String name
private int age
//定义的Getter方法所对应的属性可以直接调用
public String getScore(){
100
} //属性的Getter、Setter方法
public String setName(String name){
this.name = name
} public void getName(){
name
}
}

下面是上述代码的执行结果:

PS E:\Gradle\study\Groovy\JavaBean> gradle javaBean

> Configure project :
名字是:Gradle
年龄是:10
分数是:100 BUILD SUCCESSFUL in 2s

闭包

闭包是大多数脚本语言具有的一个特性,如 JavaScript、Groovy 等,闭包就是一个使用花括号包围的代码块,下面来学习 Groovy 中的闭包,主要有两部分:闭包及闭包参数传递和闭包委托。

闭包及其参数传递

下面来看一下如何定义一个闭包以及相关参数的传递,直接上代码:

task closure{
//自定义闭包的执行
mEach{
println it
} //向闭包传递参数
mEachWithParams{m,n -> //m,n ->将闭包的参数和主体区分离开来
println "${m} is ${n}"
}
} //1.定义一个方法,参数closure用于接收闭包
//2.闭包的执行就是花括号里面代码的执行
//3.闭包接收的参数就是闭包参数closure参数中的i,如果是一个参数默认就是it变量
def mEach(closure){
for(int i in 1..5){
closure(i)
}
} //向闭包传递参数
def mEachWithParams(closure){
def map = ["name":"Groovy","age":10]
map.each{
closure(it.key, it.value)
}
}

上面代码中定义了闭包以及如何进行闭包的参数的传递,当闭包只有一个参数时,默认就是 it,反之闭包有多个参数时,就需要将参数定义出来,具体可参考上述代码,下面是执行结果:

PS E:\Gradle\study\Groovy\Closure> gradle delegate

> Configure project :
1
2
3
4
5
name is Groovy
age is 10 BUILD SUCCESSFUL in 2s

闭包委托

Groovy 闭包的强大之处在于它支持闭包方法的委托,Groovy 的闭包有三个属性:thisObject、owner、delegate,当在一个闭包中调用定义的方法时,由这三个属性来确定该方法由哪个对象来执行,默认 owner 和 delegate 是相等的,其中 delete 是可以被修改的,Gradle 中闭包的很多功能都是通过修改 delegate 来实现的。下面通过定义一个闭包以及方法,通过打印来说明这三个属性的一些区别:

//闭包的委托
task delegate{
new Delegate().test{
//Groovy闭包的三个属性:thisObject、owner、delegate
println "thisObject:${thisObject.getClass()}"
println "owner:${owner.getClass()}"
println "delegate:${delegate.getClass()}" //闭包默认it
println "闭包默认it:"+it.getClass() //定义的方法,优先使用thisObject来处理
method()
//闭包中的方法
it.method()
}
} def method(){
println "mththod in root:${this.getClass()}"
} class Delegate{
def method(){
println "mththod in Delegate:${this.getClass()}"
} //闭包
def test(Closure<Delegate> closure){
closure(this);
}
}

下面是上述代码的执行结果,参考如下:

PS E:\Gradle\study\Groovy\Closure> gradle delegate

> Configure project :

thisObject:class build_3ajca04o1rprxygcsq0ajvt7i
owner:class build_3ajca04o1rprxygcsq0ajvt7i$_run_closure2
delegate:class build_3ajca04o1rprxygcsq0ajvt7i$_run_closure2
闭包默认it:class Delegate
mththod in root:class build_3ajca04o1rprxygcsq0ajvt7i
mththod in Delegate:class Delegate BUILD SUCCESSFUL in 2s

当在闭包中调用方法 method() 时,发现是 thisObject 调用了 method() 方法,而不是 owner 或 delegate,说明闭包中优先使用 thisObject 来处理方法的执行,同时可以看到 owner 和 delegate 是一致的,但是 owner 比 delegate 的优先级要高,所以闭包中方法的处理顺序是:thisObject > owner > delegate。

Gradle 中一般会指定 delegate 为当前的 it,这样我们将可以通过 delegate 指定的对象来操作 it 了,下面指定闭包的 delegate 并设置委托优先,让委托的具体对象来执行其方法,下面是测试代码:


task student{
configStudent{
println "当前it:${it}" name = "Groovy"
age = 10
getInfo()
}
} class Student{
String name
int age
def getInfo(){
println "name is ${name}, age is ${age}"
}
} def configStudent(Closure<Student> closure){
Student student = new Student()
//设置委托对象为当前创建的Student实例
closure.delegate = student
//设置委托模式优先,如果不设置闭包内方法的处理者是thisObject
closure.setResolveStrategy(Closure.DELEGATE_FIRST)
//设置it变量
closure(student)
}

下面是上述代码的执行结果,参考如下:

PS E:\Gradle\study\Groovy\Closure> gradle student

> Configure project :

当前it:Student@18f6d755
name is Groovy, age is 10 BUILD SUCCESSFUL in 2s

总结

学习 Groovy 的目的还是为了加深对 Gradle 构建工具的理解,上面通过五个方面对 Groovy 有了初步的人认识,后续如果有需要在看 Groovy 的高级用法。

如果感兴趣,可以关注公众号:躬行之(jzman-blog),一起交流学习。

Gradle系列之Groovy基础篇的更多相关文章

  1. 手摸手,带你用Beego撸商城系列一(基础篇)

    完整项目地址: go-shop-b2c 系列文章: 手摸手,带你用 Beego撸商城 系列一(基础篇) 手摸手,带你用 Beego撸商城 系列二(登录篇) 手摸手,带你用 Beego撸商城 系列三(系 ...

  2. Gradle+Groovy基础篇

    在Java项目中,有两个主要的构建系统:Gradle和Maven.构建系统主要管理潜在的复杂依赖关系并正确编译项目.还可以将已编译的项目以及所有资源和源文件打包到.war或.jar文件中.对于简单的构 ...

  3. Gradle系列之一 Groovy语法精讲

    Gradle技术之一 Groovy语法精讲 gradle脚本是基于groovy语言开发的,想要学好gradle必须先要对groovy有一个基本的认识 1. Groovy特点 groovy是一种DSL语 ...

  4. [Android 性能优化系列]内存之基础篇--Android怎样管理内存

    大家假设喜欢我的博客,请关注一下我的微博,请点击这里(http://weibo.com/kifile),谢谢 转载请标明出处(http://blog.csdn.net/kifile),再次感谢 原文地 ...

  5. 探索ASP.NET MVC5系列之~~~1.基础篇---必须知道的小技能

    其实任何资料里面的任何知识点都无所谓,都是不重要的,重要的是学习方法,自行摸索的过程 汇总:http://www.cnblogs.com/dunitian/p/4822808.html#mvc 本章D ...

  6. asp.net core 系列之中间件基础篇(middleware)

    中间件是一种插入到管道上进行处理请求和响应的软件:每个中间件组件具有下面的功能: 选择是否把请求传递到管道上的下一个组件 可以在下一个组件的之前和之后做处理工作 请求委托(request delega ...

  7. Gradle系列之构建脚本基础

    原文发于微信公众号 jzman-blog,欢迎关注交流. 前面两篇文章分别介绍了 Gradle 基础知识以及 Groovy 相关基础知识,这也是学习 Gradle 所必需了解的,文章链接如下:: Gr ...

  8. Gradle系列之Android Gradle基础配置

    原文发于微信公众号 jzman-blog,欢迎关注交流. 通过前面几篇文章学习了 Gradle 基础知识以及 Gradle 插件相关的知识,关于 Gradle 及其插件相关知识请先阅读下面几篇文章: ...

  9. SQL系列总结——基础篇(一)

       数据库与表.列的关系其实就像是一个Excel工作薄(workbook)与Excel表格(sheet)以及表格中的列的关系一样.关系数据库中最基本的对象有3个:表.列.用户     基本的概念名词 ...

随机推荐

  1. docker image换包步骤

    Docker Commit 1.在IDEA中通过maven package得到watchman-1.5.0-SNAPSHOT.jar,将其scp到baisheng1本地: 2.查看dbaservice ...

  2. HDU 4325 Flowers 树状数组+离散化

    Flowers Problem Description As is known to all, the blooming time and duration varies between differ ...

  3. OpenCV-Python Shi-tomas拐角检测器和益于跟踪的特征 | 三十八

    目标 在本章中, 我们将学习另一个拐角检测器:Shi-Tomasi拐角检测器 我们将看到以下函数:cv.goodFeaturesToTrack() 理论 在上一章中,我们看到了Harris Corne ...

  4. coding++ :JS-判断当前是否是IE浏览器,并返回时IE几?

    IEVersion(); function IEVersion() { var userAgent = navigator.userAgent; //取得浏览器的userAgent字符串 var is ...

  5. 已知IP地址和子网掩码求出网络地址、广播地址、地址范围和主机数(转载https://blog.csdn.net/qq_39026548/article/details/78959089)

    假设IP地址为128.11.67.31,子网掩码是255.255.240.0.请算出网络地址.广播地址.地址范围.主机数.方法:将IP地址和子网掩码转化成二进制形式,然后进行后续操作. IP地址和子网 ...

  6. win10 系统中vscode 的终端 shell 设置

    今天,打算开始搞一个个人博客小项目. 主力台式电脑在实验室,于是重新配了一下自己的小破笔记本.系统是之前自己捣鼓的 win10 .在打开终端调试 node 时,发现报了这么一个错. 我刚开始以为是自己 ...

  7. Spring Boot整合Thymeleaf视图层

    目录 Spring Boot整合Thymeleaf Spring Boot整合Thymeleaf 的项目步骤 Thymeleaf 语法详解 Spring Boot整合Thymeleaf Spring ...

  8. linux 之虚拟机的安装与介绍

    linux 零基础入门1.1linux介绍 操作系统用途: 管理硬件 驱动硬件 管理软件 分配资源1.2 linux的发展unix -> windows ->linuxlinux 免费 开 ...

  9. bs4使用

    目录 安装使用 遍历文档树 查找文档树 安装使用 # 安装 pip3 install beautifulsoup4 from bs4 import BeautifulSoup soup=Beautif ...

  10. webpack4.x 从零开始配置vue 项目(三)

    目标 babel 转换ES6 语法 postCss 增强css功能,如自动增加前缀 vue-loader 解析vue 文件 实现基本的vue项目开发环境,打包等 Babel 由于浏览器对es6语法兼容 ...