Groovy
The Apache Groovy programming language
Download https://groovy.apache.org/download.html
Groovy 是基于 JVM 虚拟机的一种动态语言,它的语法和 Java 非常相似,由 Java 入门 Groovy,基本上没有任何障碍。Groovy 完全兼容 Java,又在此基础上增加了很多动态类型和灵活的特性,比如支持闭包,支持 DSL,可以说它是一门非常灵活的动态脚本语言。
Groovy 的特性虽然不多,但也有一些,我们不可能在这里都讲完,在这里我挑一些和 Gradle 有关的知识讲,让大家很快的入门 Groovy,并且能看懂这门脚本语言,知道在 Gradle 为什么这么写。其次是每个 Gradle 的 build 脚本文件都是一个 Groovy 脚本文件,你可以在里面写任何符合 Groovy 的代码,比如定义类,生命函数,定义变量等等,而 Groovy 又完全兼容 Java,这就意味着你可以在 build 脚本文件里写任何的 Java 代码,非常灵活方便。
示例
1 | class Example { |
字符串
字符串,每一门语言都会有对字符串的处理,Java 相对要稍微复杂一些,限制比较多,相比而言,Groovy 非常方便,比如字符串的运算、求值、正则等等。
从现在开始我们算是正式的介绍 Groovy 了,在此之前我们先要知道,在 Groovy 中,分号不是必须的。相信很多用 Java 的朋友都习惯了,每一行的结束必须有分号,但是 Groovy 没这个强制规定,所以你看到的 Gradle 脚本很多都没有分号,其实这个是 Groovy 的特性,而不是 Gradle 的。没有分号的时候,我们每一行默认为有分号就好了。
在 Groovy 中,单引号和双引号都可以定义一个字符串常量(Java 里单引号定义一个字符),不同的是单引号标记的是纯粹的字符串常量,而不是对字符串里的表达式做运算,但是双引号可以。
- 单引号没有运算的能力,它里面的所有都是常量字符串。
- 双引号可以直接进行表达式计算的这个能力非常好用,我们可以用这种方式进行字符串链接运算,再也不用 Java 中繁琐的 +号了。记住这个嵌套的规则,一个美元符号紧跟着一对花括号,花括号里放表达式,比如
${name}
,${1+1}
等等,只有一个变量的时候可以省略花括号,比如$name
。
1 | task printStringVar << { |
集合
集合,也是我们在 Java 中经常用到的,Groovy 完全兼容了 Java 的集合,并且进行了扩展,使得生命一个集合,迭代一个集合、查找集合的元素等等操作变得非常容易。常见的集合有 List、Set、Map 和 Queue,这里我们只介绍常用的 List 和 Map。
List
1 | task list << { |
Map
1 | task map << { |
对于集合,Groovy 还提供了诸如 collect、find、findAll 等便捷的方法,有兴趣的朋友可以找相关文档。
方法
- 括号是可以省略的
- return 是可以不写的
1 | task testMethod <<{ |
代码块是可以作为参数传递的
代码块–一段被花括号包围的代码,其实就是我们后面要将的闭包,Groovy 是允许其作为参数传递的,但是结合这我们上面方法的特性,最后的基于闭包的方法调用就会非常优雅、易读。以我们的集合的 each 方法为例,它接受的参数其实就是一个闭包。
JavaBean
1 | task testJavaBean << { |
闭包
闭包是 Groovy 的一个非常重要的特性,可以说他是 DSL 的基础。闭包不是 Groovy 的首创,但是它支持这一重要特性,这就使用我们的代码灵活、轻量、可复用,再也不用像 Java 一样动不动就要搞一个类了,虽然 Java 后来有了匿名内部类,但是一样冗余不灵活。
初识闭包
前面我们讲过,闭包其实就是一段代码块,下面我们就一步步实现自己的闭包,了解闭包的 it 变量的由来。集合的 each 方法我们已经非常熟悉了,我们就以其为例,实现一个类似的闭包功能。
在上面的例子中我们定义了一个方法 customEach,它只有一个参数,用于接收一个闭包(代码块),那么这个闭包如何执行呢?很简单,跟一对括号就是执行了,会 JavaScript 的朋友是不是觉得很熟悉,把它当做一个方法调用,括号里的参数就是该闭包接收的参数,如果只有一个参数,那么就是我们的 it 变量了。
向闭包传递参数
当闭包有一个参数时,默认就是 it;当有多个参数是,it 就不能表示了,我们需要把参数一一列出。
1 | task helloClosure << { |
闭包委托
Groovy 闭包的强大之处在于它支持闭包方法的委托。Groovy 的闭包有 thisObject、owner、delegate 三个属性,当你在闭包内调用方法时,由他们来确定使用哪个对象来处理。默认情况下 delegate 和 owner 是相等的,但是 delegate 是可以被修改的,这个功能是非常强大的,Gradle 中的很闭包的很多功能都是通过修改 delegate 实现的。
1 | task testDelegate << { |
运行我们可以看到输出:
闭包内方法的处理顺序是 thisObject > owner > delegate。
DSL
DSL(Domain Specific Language),领域特定语言,说白了就是专门关注某一领域专门语言,在于专,而不是全,所以才叫领域特定的,而不是像 Java 这种通用全面的语言。
Gradle 就是一门 DSL,他是基于 Groovy 的,专门解决自动化构建的 DSL。自动化构建太复杂、太麻烦、太专业,我们理解不了,没问题,专家们就开发了 DSL–Gradle,我们作为开发者只要按照 Gradle DSL 定义的,书写相应的 Gradle 脚本就可以达到我们自动化构建的目的,这也是 DSL 的初衷。
DSL 涉及的东西还有很多,这里我们简单的提一下概念,让大家有个了解,关于这方便更详细的可以阅读世界级软件开发大师 Martin Fowler 的《领域特定语言》。
参考
Groovy 教程 w3cschool
https://www.w3cschool.cn/groovy/
本文纯属自学历程 + 一些记录,绝大部分内容来自原书 Android Gradle 权威指南。觉得对你有用,请支持原书。