前言
Gradle的构建脚本是采用Groovy语言编写的。Groovy是Java平台上设计的一种强大的、可选类型和动态的语言。Groovy可以无缝地集成任何Java程序,并立即让你的应用程序拥有强大的特性,包括脚本功能、DSL、运行时和编译时元编程和函数式编程。
基础知识
Groovy语言的特点:
- 基于Java虚拟机的一种灵活而动态的语言
- 可以无缝集成所有的Java类和库
- 可以直接编译为Java字节码,用在任何可以使用Java的地方
- 基于Java但是同时拥有Python、Ruby和Smalltalk等语言的强大特性
- 支持DSL和其它紧凑的语法,使得代码易于阅读和维护
- 支持脚本功能
- 支持可选类型
下载和安装
Groovy SDK的下载地址:http://groovy-lang.org/download.html
这里介绍一下如何安装Groovy的二进制发行版:
- 下载并解压Groovy的二进制发行版
- 设置 GROOVY_HOME 环境变量的值为解压的目录
- 添加 GROOVY_HOME/bin 路径到 PATH 环境变量中
- 设置 JAVA_HOME 环境变量的值为JDK的目录
安装完毕之后可以通过"groovy --version"命令来验证是否安装成功。如果安装成功,那么命令行将输出Groovy的版本号。如下所示:
$ groovy --version
Groovy Version: 2.4.12 JVM: 1.8.0_92 Vendor: Oracle Corporation OS: Windows 7
工具
groovy
groovy调用了Groovy命令行处理器,它可以执行行内Groovy表达式和Groovy文件中的脚本、测试程序或者应用程序。groovy命令的作用与Java语言的java命令类似。
执行一个Groovy脚本、测试程序或者应用程序的最简单方法是:
$ groovy MyScript.groovy
其中,.groovy 部分是可选的。groovy命令支持许多命令行参数,具体请参考官方文档。例如,执行行内Groovy表达式:
$ groovy -e "println new Date()"
Wed Aug 23 01:12:10 CST 2017
groovyc
groovyc是Groovy编译器的命令行工具,它允许你编译Groovy源代码为Java字节码。groovyc命令的作用与Java语言的javac命令相同。
编译一个Groovy脚本或者类的最简单方法是:
$ groovyc MyClass.groovy
这将生成一个MyClass.class文件。同样,groovyc命令也支持许多命令行参数,具体请参考官方文档。
Hello World
Groovy支持类和脚本。我们将采用类和脚本两种方式来编写Hello World程序。
类方式
新建HelloWorld.groovy文件,输入如下代码:
public class HelloWorld {
public static void main(String[] args) {
System.out.println("Hello World!");
}
}
在命令行输入"groovy HelloWorld.groovy"命令执行代码。结果如下所示:
$ groovy HelloWorld.groovy
Hello World!
可以看到编写一个Groovy类与编写一个Java类很相似。Groovy的语法在Java的基础上做了许多简化。所以,上面的类也可以写成如下代码:
class HelloWorld {
static void main(String[] args) {
println "Hello World!"
}
}
在命令行输入"groovy HelloWorld.groovy"命令执行代码。结果如下所示:
$ groovy HelloWorld.groovy
Hello World!
可以看到输出结果一样。
脚本方式
清空文件内容,输入如下代码:
println "Hello World!"
在命令行输入"groovy HelloWorld.groovy"命令执行代码。结果如下所示:
$ groovy HelloWorld.groovy
Hello World!
可以看到同样输出了"Hello World!"字符串。
语义
可选性
可选的括号
如果方法调用至少有一个参数并且没有歧义,那么可以省略括号。例如:
println "Hello World"
def maximum = Math.max 5, 10
如果方法调用没有参数或者有歧义,那么需要圆括号。例如:
println()
println(Math.max(5, 10))
可选的分号
如果一行代码仅包含一条语句,那么在该行末尾的分号可以省略。例如:
assert true
一行代码中的多个语句需要分号来分隔它们。例如:
boolean a = true; assert a
可选的return关键字
在Groovy中,一个方法或者闭包的最后一个表达式的值被返回。因此,return关键字是可选的。例如,下面这段代码:
int add(int a, int b) {
return a+b
}
assert add(1, 2) == 3
可以简化为:
int add(int a, int b) {
a+b
}
assert add(1, 2) == 3
可选的public关键字
默认情况下,Groovy的类和方法都是public的。例如,下面这个类:
class Server {
String toString() {
"a server"
}
}
等同于下面这个类:
public class Server {
public String toString() {
"a server"
}
}
可选的类型定义
脚本中的变量不需要类型定义。例如,下面这个脚本:
int x = 1
int y = 2
assert x+y == 3
等同于下面这个脚本:
x = 1
y = 2
assert x+y == 3
语句
变量定义
Groovy支持可选类型。变量可以使用它们的具体类型或者 def 关键字来定义。例如:
String x
def o
def是类型名的替换,它表示你不关心这个变量的类型。在定义类中的变量时,要么显式地提供类型名,要么使用def来替换。这是为了让Groovy解析器可以检测到变量定义。你可以将def看作是 Object 的别名,这样就可以立即理解它。
变量赋值
你可以为变量赋值然后在后面使用。例如:
x = 1
println x
x = new java.util.Date()
println x
x = -3.1499392
println x
x = false
println x
x = "Hi"
println x
Groovy支持一次赋值多个变量。例如:
def (a, b, c) = [10, 20, 'foo']
assert a == 10 && b == 20 && c == 'foo'
控制结构
Groovy中的switch语句兼容Java中的switch语句。不同的是,Groovy的switch语句可以处理任何类型的switch值,并且可以执行不同类型的匹配。例如:
def x = 1.23
def result = ""
switch ( x ) {
case "foo":
result = "found foo"
// lets fall through
case "bar":
result += "bar"
case [4, 5, 6, 'inList']:
result = "list"
break
case 12..30:
result = "range"
break
case Integer:
result = "integer"
break
case Number:
result = "number"
break
case ~/fo*/: // toString() representation of x matches the pattern?
result = "foo regex"
break
case {
it < 0 }: // or { x < 0 }
result = "negative"
break
default:
result = "default"
}
assert result == "number"
assertion语句
与Java相比,assert关键字在Groovy中的表现非常不同。首先,Groovy中的assertion语句总是被执行,独立于JVM的-ea标志。这使得assertion语句成为单元测试的第一选择。
一个assertion语句被分解为3个部分:
assert [left expression] == [right expression] : (optional message)
其次,assertion语句的结果与在Java中得到的结果非常不同。如果assertion语句的结果为true,那么什么也不会发生。如果assertion语句的结果为false,那么它将提供对所断言表达式的每个子表达式的值的可视化表示。例如:
assert 1+1 == 3
执行结果如下所示:
$ groovy test.groovy
Caught: Assertion failed:
assert 1+1 == 3
| |
2 false
Assertion failed:
assert 1+1 == 3
| |
2 false
at test.run(test.groovy:1)
如果你不想要像上面那样的打印错误信息,你可以通过更改assertion语句的可选信息部分来返回自定义的错误信息。例如:
assert 1+1 == 3 : 'Incorrect computation result'
执行结果如下所示:
$ groovy test.groovy
Caught: java.lang.AssertionError: Incorrect computation result. Expression: ((1 + 1) == 3)
java.lang.AssertionError: Incorrect computation result. Expression: ((1 + 1) == 3)
at test.run(test.groovy:1)
语法
Groovy的语法源自Java语法,但是在Java语法的基础上进行了一定的增强和简化。
注释
Groovy支持单行注释和多行注释。例如:
// a standalone single line comment
println "hello" // a comment till the end of the line
/* a standalone multiline comment
spanning two lines */
println "world" /* a multiline comment starting
at the end of a statement */
println 1 /* one */ + 2 /* two */
Groovy也支持一种特殊的行注释,在UNIX系统中通常叫做 shebang 行。它允许脚本直接从命令行执行,前提是你已经安装了Groovy发行版,并且groovy命令可以在PATH环境变量下使用。例如:
#!/usr/bin/env groovy
println "Hello from the shebang line"
在命令行直接执行脚本。如下所示:
$ ./test.groovy
Hello from the shebang line
关键字
Groovy语言所有的关键字如下表所示:
Keywords | Keywords | Keywords | Keywords |
---|---|---|---|
as | assert | break | case |
catch | class | const | continue |
def | default | do | else |
enum | extends | false | finally |
for | goto | if | implements |
import | in | instanceof | interface |
new | null | package | return |
super | switch | this | throw |
throws | trait | true | try |
while |
与Java相比,Groovy语言新增了4个关键字:as、def、in、trait。
Strings
Groovy支持两种字符串实例:java.lang.String 和 groovy.lang.GString
单引号字符串。例如:
'a single quoted string'
单引号字符串是普通的java.lang.String,不支持插值。
双引号字符串。例如:
"a double quoted string"
如果没有插值表达式,那么双引号字符串是普通的java.lang.String。反之,如果有插值表达式,那么双引号字符串是groovy.lang.GString。
任何Groovy表达式都可以插值到所有的字符串中,除了单引号和三引号字符串之外。插值是将字符串中的占位符替换为字符串的值。占位符表达式使用