原文见深入理解Android
基本概念
println "hello groovy"
//定义变量,不必显示指定类型
def va1 = 1
def var2 = "I am a person"
def int val3 = 3
//定义函数,关键字return不是必须的
String testFunction(arg1, arg2) {
"xxxx"
}
println testFunction(1, 2)
//无返回值的函数必须使用def定义,默认返回null
def funcWithoutReturnVal() {
}
println funcWithoutReturnVal()
//一般字符串使用单引号定义
def singleQuote = 'I am $ dolloar'
//$符号在双引号的定义的字符串中被用来插入变量的值
def x = 1
def doubleQuoteWithDollar = "I am $x dolloar"
println doubleQuoteWithDollar
//三引号的字符串按原样打印
def multiLines = ''' begin
line 1
line 2
end'''
println multiLines
//every thing in groovy is object
def int xy = 1
println x.getClass().getCanonicalName()
容器类型
//List
def aList = [5, 'string', true]
assert aList[1] == 'string'
//List会自动扩容,不用担心越界
assert aList[5] == null
aList[100] = 100
assert aList[100] == 100
println aList.size
//Map
//key must be string
def aMap = ['key1':'value1', 'key2':true]
//Map的键只能为字符串,因而可以不用引号
def aNewMap = [key1:'value1', key2:true]
//使用变量值作为键
def key1="wowo"
def aConfusedMap = [(key1):"who am i?"]
//获取Map内的值
println aMap.key1
println aMap['key1']
//向Map内添加键值对
aMap.newKey = "new value"
//Range
//Range是List的扩展
//包括尾端元素
def aRange = 1..5
//不包含尾端元素
def aRangeWithoudEnd = 1..<5
println aRange.from
println aRange.to
闭包
//包括两个形参闭包
def aClosure = {
param1, param2 ->
return param1+param2
}
//默认使用it变量来访问实参
def bClosure = {
return aClosure("a", "b $it")
}
println aClosure("hello", "world")
println bClosure("hello")
//如果闭包是最后一个参数,不必包括在圆括号内
def iamList = [1,2,3,4,5]
iamList.each {
println it
}
def testClosure(int al, String b1, Closure closure) {
closure()
}
testClosure(4, "test") {
println "i am in closure"
}
//map过滤
def aMap = [k1:'value1', k2:true]
def results = aMap.findAll {
key, value ->
println "key=$key, value=$value"
if (key == 'k1')
return true
return false
}
类
Person.groovy
class Person {
String name
String title
Person(name, title) {
this.name = name
this.title = title
}
def print() {
println name + " " + title
}
}
test_person.groovy
def person = new Person("cmbc", "is wonderful")
person.print()
作用域
其实每个groovy脚本都会被编译成一个Java类,脚本的内容会被放入该类的run方法内,然后在JVM上运行。脚本内定义的变量因为定义的方式不同会有不同的作用域。
假如有脚本scope.groovy如下:
def x = 1
def printx() {
println x
}
//出错,找不到x。因为printx会成为一个成员方法,而x是run方法内的局部变量
printx()
去掉def关键字,该脚本可以运行正常。然而x仍然不是scope类的成员变量。另写一个脚本test_scope.groovy测试便知:
def atest = new scope()
//依旧出错
atest.printx()
原因是,x是在run方法执行的过程动态添加到scope对象中。要想x成为scope对象的成员,需要这样定义:
import groovy.transform.Field;
@Field x = 1
文件IO
def targetFile = new File("scope.groovy")
//读取每一行并打印
targetFile.eachLine {
line ->
println line
}
//获得文件的字节数组
println targetFile.getBytes()
//拷贝文件,用于演示读写文件
def srcFile = targetFile
def destFile = new File("temp")
destFile.withOutputStream {
os ->
srcFile.withInputStream {
ins ->
os << ins
}
}
XML处理
有如下xml文件
<response version-api="2.0">
<value>
<books>
<book available="20" id="1">
<title>Don xijote</title>
<author id="1">Manuel De Cervantes</author>
</book>
<book available="14" id="2">
<title>Catcher in the Rye</title>
<author id="2">JD Salinger</author>
</book>
</books>
</value>
</response>
解析的脚本如下:
import groovy.util.slurpersupport.GPathResult
def xparser = new XmlSlurper()
def targetFile = new File("x.xml")
GPathResult gpathResult = xparser.parse(targetFile)
//获取节点
def book2 = gpathResult.value.books.book[1]
def author = book2.author
//获取节点的属性
def authorId = author.@id
println author
println authorId