频道栏目
首页 > 资讯 > 其他 > 正文

Gradle 介绍(二)

16-11-16        来源:[db:作者]  
收藏   我要投稿

五、Groovy 介绍

Gradle 选择了 Groovy,Groovy 由于它基于 Java,所以这里仅介绍 Java之外的东西。了解 Groovy 语言是掌握 Gradle 的基础。

Groovy 是一种动态语言。这种语言比较有特点,它和 Java 一样,也运行于 Java 虚拟机中。你可以认为 Groovy 扩展了 Java 语言。比如,Groovy 对自己的定义就是:Groovy 是在 java 平台上的、 具有像 Python, Ruby 和Smalltalk 语言特性的灵活动态语言, Groovy 保证了这些特性像 Java 语法一样被 Java 开发者使用。

除了语言和 Java 相通外,Groovy 有时候又像一种脚本语言。前文也提到过,当我执行 Groovy 脚本时,Groovy 会先将其编译成 Java 类字节码,然后通过 Jvm 来执行这个 Java 类。图 1 展示了 Java、Groovy 和 Jvm 之间的关系。
这里写图片描述
图 1 Java、Groovy 和 JVM 的关系

实际上,由于 Groovy Code 在真正执行的时候已经变成了 Java 字节码,所以JVM 根本不知道自己运行的是 Groovy 代码。下面我们将介绍 Groovy。由于此文的主要目的是 Gradle,所以我们不会过多讨论 Groovy 中细枝末节的东西,
而是把知识点集中在以后和 Gradle 打交道时一些常用的地方上。

5.1 Groovy 开发环境

在学习本节的时候,最好部署一下 Groovy 开发环境。根据 Groovy 官网的
介绍(http://www.groovy-lang.org/download.html),部署 Groovy
开发环境非常简单,在 Ubuntu 或者 cygwin 之类的地方:
curl -s get.gvmtool.net | bash
source”$HOME/.gvm/bin/gvm-init.sh”
gvm install groovy

执行完最后一步,Groovy 就下载并安装了。
然后,创建一个 test.groovy 文件,里边只有一行代码:
println “hello groovy”
执行 groovy test.groovy,输出结果:hello groovy

另外,除了可以直接使用 JDK 之外,Groovy 还有一套 GDK,网址是:
http://www.groovy-lang.org/api.html

5.2 Groovy 语法基础

为了后面讲述方面,这里先介绍一些前提知识。
1) Groovy 注释标记和 Java 一样,支持//或者/**/
2) Groovy 语句可以不用分号结尾。
3) Groovy 中支持动态类型,即定义变量的时候可以不指定其类型。Groovy中,变量定义可以使用关键字 def。注意,虽然 def 不是必须的,但是为了代码清晰,建议还是使用 def 关键字

def variable1 = 1
//可以不使用分号结尾
def varable2 = “I am a person”
def
int x = 1 //变量定义时,也可以直接指定类型

4) 函数定义时,参数的类型也可以不指定。比如String testFunction(arg1,arg2){。。。}//无需指定参数类型
5) 除了变量定义可以不指定类型外,Groovy 中函数的返回值也可以是无类型的。比如:
//无类型的函数定义,必须使用 def 关键字
def
nonReturnTypeFunc(){
last_line
//最后一行代码的执行结果就是本函数的返回值
}
6) 如果指定了函数返回类型,则可不必加 def 关键字来定义函数
String getString(){
return”I am a string”
}
其实,
所谓的无返回类型的函数,
我估计内部都是按返回 Object 类型来处理的。
毕竟,Groovy 是基于 Java 的,而且最终会转成 Java Code 运行在 JVM 上。
7) 函数返回值:Groovy 的函数里,可以不使用 returnxxx 来设置 xxx 为函数返回值。如果不使用 return 语句的话,则函数里最后一句代码的执行结果被设置成返回值。比如

//下面这个函数的返回值是字符串”getSomething return value”
def getSomething(){
//如果这是最后一行代码,则返回类型为 String
“getSomething return value”
1000//如果这是最后一行代码,则返回类型为 Integer
}
8) 注意,如果函数定义时候指明了返回值类型的话,函数中则必须返回正确的数据类型,否则运行时报错。如果使用了动态类型的话,你就可以返回任何类型了。

5.3 Groovy 中的数据类型

Groovy 中的数据类型我们就介绍两种和 Java 不太一样的:一个是 Java 中的基本数据类型。另外一个是 Groovy 中的容器类。最后一个非常重要的是闭包。

5.3.1 基本数据类型
作为动态语言,Groovy 世界中的所有事物都是对象。所以,int,boolean 这些Java 中的基本数据类型,在 Groovy 代码中其实对应的是它们的包装数据类型。比如 int 对应为 Integer,boolean 对应为 Boolean。

5.3.2 容器类
Groovy 中的容器类很简单,就三种:
List:链表,其底层对应 Java 中的 List 接口,一般用 ArrayList 作为真正的实现类。
Map:键-值表,其底层对应 Java 中的 LinkedHashMap。
Range:范围,它其实是 List 的一种拓展。
对容器而言,我们最重要的是了解它们的用法。下面是一些简单的例子:

(1) List 类
变量定义:List 变量由[]定义,比如
def aList = [5,’string’,true] //List 由[]定义,其元素可以是任何对象
变量存取:可以直接通过索引存取,而且不用担心索引越界。如果索引超过当前链表长度,List 会自动往该索引添加元素

assert aList[1] == ‘string’
assert aList[5] == null //第 6 个元素为空
aList[100] = 100 //设置第 101 个元素的值为 10
assert aList[100] == 100
那么,aList 到现在为止有多少个元素呢?
println aList.size ===>结果是 101

(2) Map 类
变量定义:Map 变量由[:]定义,比如
def aMap = [‘key1’:’value1’,’key2’:true]
Map 由[:]定义,注意其中的冒号。冒号左边是 key,右边是 Value。key 必须是
字符串,value 可以是任何对象。另外,key 可以用”或”“包起来,也可以不用引
号包起来。比如:
//其中的 key1 和 key2 默认被处理成字符串”key1”和”key2”

def aNewMap = [key1:”value”,key2:true]
不过 Key 要是不使用引号包起来的话,也会带来一定混淆,比如

def key1=”wowo”
def aConfusedMap=[key1:”who am i?”]

aConfuseMap 中的 key1 到底是”key1”还是变量 key1 的值“wowo”?显然,答案是字符串”key1”。如果要是”wowo”的话,则 aConfusedMap 的定义必须设置成:
def aConfusedMap=[(key1):”who am i?”]
Map 中元素的存取更加方便,它支持多种方法:
println aMap.keyName <==这种表达方法好像 key 就是 aMap 的一个成员变量一样
println aMap[‘keyName’] <==这种表达方法更传统一点

(3) Range 类
Range 是 Groovy 对 List 的一种拓展,变量定义和大体的使用方法如下:
def aRange = 1..5 <==Range 类型的变量 由 begin 值+两个点+end 值表示
这个 aRange 包含 1,2,3,4,5 这 5 个值
如果不想包含最后一个元素,则
def aRangeWithoutEnd = 1..<5
<==包含 1,2,3,4 这 4 个元素
前面讲这些东西,主要是让大家了解 Groovy 的语法。
实际上在 coding 的时候,是离不开 SDK 的。Groovy 的 API 文档位于:
http://www.groovy-lang.org/api.html

5.4 闭包

5.4.1 闭包的样子
闭包,英文叫 Closure,是 Groovy 中非常重要的一个数据类型或者说一种概念了。它代表了一段可执行的代码。其外形如下:
def aClosure = { //闭包是一段代码,所以需要用花括号括起来

//这个箭头很关键。箭头前面是参数定义,箭头后面是代码
Stringparam1, int param2 ->
println”this is code” //这是代码,最后一句是返回值,
//也可以使用 return,和 Groovy 中普通函数一样
}
简而言之,Closure 的定义格式是:
说实话,从 C/C++语言的角度看,闭包和函数指针很像。闭包定义好后,要调
用它的方法就是:
闭包对象.call(参数)
或者更像函数指针调用的方法:
闭包对象(参数)
比如:
aClosure.call(“this is string”,100)
或者
aClosure(“this is string”, 100)
上面就是一个闭包的定义和使用。在闭包中,还需要注意一点:
如果闭包没定义参数的话,则隐含有一个参数,这个参数名字叫 it,和 this 的作用类似。it 代表闭包的参数。
比如:
def greeting = { “Hello, it!”}
assertgreeting(‘Patrick’)==‘Hello,Patrick!’
等同于:
defgreeting={it->“Hello,it!”}
assert greeting(‘Patrick’) == ‘Hello, Patrick!’

5.4.2 Closure 使用中的注意点
1.
省略圆括号
闭包在 Groovy 中大量使用,比如很多类都定义了一些函数,这些函数最后一个参数都是一个闭包。比如:
public static List each(List self, Closure closure)

上面这个函数表示针对 List 的每一个元素都会调用 closure 做一些处理。
这里的closure,就有点回调函数的感觉。但是,在使用这个 each 函数的时候,我们传递一个怎样的 Closure 进去呢?比如:

def iamList = [1,2,3,4,5]
iamList.each{
//定义一个 List
println it
}

上面代码有两个知识点:
each 函数调用的圆括号不见了!原来,Groovy 中,当函数的最后一个参数是闭包的话,可以省略圆括号。比如
def testClosure(int a1,String b1, Closure closure){
//dosomething
closure() //调用闭包
}
那么调用的时候,就可以免括号!
testClosure (4, “test”, {
println”i am in closure”
})
//红色的括号可以不写..
注意,这个特点非常关键,因为以后在 Gradle 中经常会出现这样的代码:
task hello{
doLast{
println’Hello world!’
}
}
省略圆括号虽然使得代码简洁,看起来更像脚本语言,但是它这经常会让我
confuse,以 doLast 为例,完整的代码应该按下面这种写法:
doLast({
println’Hello world!’
})
有了圆括号,你会知道 doLast 只是把一个 Closure 对象传了进去。很明显,它代表这段脚本解析到 doLast 的时候就会调用 println ‘Hello world!’ 。
但是把圆括号去掉后,就感觉好像 println ‘Hello world!’立即就会被调用一样!

5.5 更多

作为一门语言,Groovy 是复杂的,是需要深入学习和钻研的。一本厚书甚至都无法描述 Groovy 的方方面面。Anyway,从使用角度看,尤其是又限定在Gradle 这个领域内,能用到的都是 Groovy 中一些简单的知识。

相关TAG标签
上一篇:Android : Android Studio技巧
下一篇:videoview实现视频引导页及从assets文件中读取文件到本地SD卡
相关文章
图文推荐

关于我们 | 联系我们 | 广告服务 | 投资合作 | 版权申明 | 在线帮助 | 网站地图 | 作品发布 | Vip技术培训 | 举报中心

版权所有: 红黑联盟--致力于做实用的IT技术学习网站