首先感谢翻译《Groovy in Action》Part 1的吴翊,其次感谢Groovy之父James Strachan
本文基于Groovy 1.8。
======== 分割线 开始于2014-12-1 ========
1,Groovy开始运行
Groovy定义和特性:
是一个基于Java虚拟机的敏捷动态语言。举例,通过groovy控制台,输入如下代码来输出当前目录下所有的文件名(递归):
构建在强大的Java语言之上 并添加了从Python,Ruby和Smalltalk等语言中学到的诸多特征。
为Java开发者提供了现代最流行的编程语言特性,而且学习成本很低(几乎为零)。
支持DSL(Domain Specific Languages领域定义语言)和其它简洁的语法,让你的代码变得易于阅读和维护。
Goovy拥有处理原生类型,面向对象以及一个Ant DSL,使得创建Shell Scripts变的非常简单。
在开发Web,GUI,数据库或控制台程序时 通过减少框架性代码 大大提高了开发者的效率。
支持单元测试和模拟(对象),可以简化测试。
无缝集成 所有已经存在的 Java对象和类库。
直接编译成Java字节码,这样可以在任何使用Java的地方 使用Groovy。
groovy -e "new File('.').eachFileRecurse { println it }" // -e 直接执行
和相同功能的java类相比,效率高低立见。
运行groovy的3种方式:
- groovysh:脚本命令行REPL
- groovyConsole:开启GUI交互界面,上面是脚本编辑区,下半部分是输出,运行快捷键Ctrl + r
- groovy:执行脚本文件,可带参数
举例,执行groovy脚本:
// Fibonacci.groovy
current = 1
next = 1
10.times { //循环10次
print current + ' '
newCurrent = next
next = next + current
current = newCurrent
}
println ''
groovy Fibonacci
===>1 1 2 3 5 8 13 21 34 55
2,语法基础
#!/usr/bin/groovy
/*BookTest.groovy
多行注释 不要命名成Book.groovy,报错:
One of the classes is an explicit generated class using the class statement,
the other is a class generated from the script body based on the file name.
*/
class Book{
String title
}
def groovyBook = new Book()
groovyBook.title = 'GIA'
assert groovyBook.title == 'GIA' // 单行注释 断言当前值equal(),非引用
// 引号中的串是GString类型,能作占位符
def nick = 'Gina'
def book = 'Groovy in Action'
assert "$nick is $book" == 'Gina is Groovy in Action'
// =~表示匹配,/正则表达式/
assert 'a12345' =~ /\d+/
// 所有的值都是对象
def x = 1
assert x + 2 == 3
assert x instanceof Integer
// 简化集合操作
def roman = ['', 'I', 'II', 'III', 'IV', 'V', 'VI', 'VII']
roman[8] = 'VIII'
assert roman.size() == 9 // 实是List,能自动扩容
assert roman instanceof List
def y = 1..<10 // range形式,从1起,到10止,不包括10
assert y.contains(10) == false
assert y.size() == 9
assert y.from == 1
assert y.to == 9
assert y.reverse() == 9..1
assert y instanceof List
def http = [
100 : 'CONTINUE',
200 : 'OK',
400 : 'BAD REQUEST'
]
assert http[200] == 'OK' // 实是Map,冒号区分KV,通过下标Key找配对的Value
assert http instanceof Map
3,闭包Closure
泛用于函数式语言,类Lambda,使代码块被当成数据来引用执行,典型应用是回调函数,用{}包围,如果没有return,则闭包内的最后一行代码就是返回值。
/*
ClosrueTest.groovy
闭包举例
*/
[1, 2, 3].each{entry -> println entry} // 枚举打印
log = ''
(1..10).each{ log += it } // 闭包参数隐式参数
assert log == '12345678910'
map = ['a':1, 'b':2]
def doubleMethod (entry) {
map[entry.key] = entry.value *2
}
doubler = this.&doubleMethod // 应用方法作为闭包
map.each(doubler)
assert map == ['a':2, 'b':4]
4,结构控制
if (null){ // 非null为真
assert false
}else{
assert true
}
def clinks = 0
for (remainingGuests in 0..9) { // range迭代
clinks += remainingGuests
}
assert clinks == (10*9)/2
def age = 36
switch(age){ // range case
case 16..20 : rate = 0.5 ; break
case 21..60 : rate = 0.7 ; break
default : rate = 0
}
assert rate == 0.7
5,数据类型
Groovy中所有数据都是对象。
5.1,数字
- 整数默认为Integer,小数点默认为BigDecimal;
- 数值类型间自动转换包装;
- 1 + 1 实质是1.plus(1)的简写;
def store = ''
0.step(10, 2) { num -> // 数字自带糖,如步进
store += num + ' '
}
assert store == '0 2 4 6 8 '
5.2,字符串GString
comm = '''line 1
line 2
line 3'''
println comm // 三组引号表示多行文本
zz = /\d+/
println zz // 以/起止的串内容不转义,多用于正则表达式
date = new Date()
out = "Date is ${date.toGMTString()}!" // 变量作为模板占位符的完整写法,好东西
println out
out.strings.each{entry -> println entry}
out.values.each{entry -> println entry} // 实际是混合的,动态部分独立
println 'x'.padLeft(3)
println 'x'.center(3)
println 'x' * 3 // 各种糖
greeting = 'Hello'
greeting <<= ' Groovy'
greeting[1..4] = 'i' // 追加&替换
assert greeting instanceof java.lang.StringBuffer
println greeting
5.3,正则表达式
greeting = 'sunshine beach beauty'
assert greeting =~ /b.a/ // 含有以s开头、n结尾的3位字符
finder = (greeting =~ /b.a/)
assert finder instanceof java.util.regex.Matcher
word = /\w+/
matches = (greeting ==~ /($word $word)*/) // 有否有空格包围的词组,boolean
println matches
found = ''
finder.each{ match -> // 匹配结果传递给闭包
found += match + ' '
}
println found
5.4,集合容器
mylist = ['a', 'b', 'c', 'd', 'e']
assert mylist[0..2] == ['a', 'b', 'c'] // getAt
mylist[0,4] = ['x', 'y']
assert mylist == ['x', 'b', 'c', 'd', 'y'] // putAt
mylist[1..3] = []
assert mylist == ['x', 'y'] // remove
println mylist[-1] // 负数逆向索引
mylist += ['z'] assert mylist == ['x', 'y', 'z'] // plus
assert mylist.isCase('x') // 用于switch
assert ['a', 'b', 'x'].grep(mylist) == ['x'] // 过滤,不能直接print
assert ['a', 'b', 'x'].intersect(mylist) == ['x'] // 交集
assert ['a', 'b'].disjoint(mylist) // 非交判定
println mylist.pop() // 堆弹出
if ([]) assert false // 空集合为假
def list = [[1, 0], [0,1,2]]
list = list.sort {a,b -> a[0] <=> b[0]} // 首元素对比排序
println list
def quickSoft(list) { // 快速排序算法
if (list.size() < 2) return list
def pivot = list[list.size().intdiv(2)]
def left = list.findAll {item -> item < pivot}
def middle = list.findAll {item -> item == pivot}
def right = list.findAll {item -> item > pivot}
return (quickSoft(left) + middle + quickSoft(right))
}
assert quickSoft([2,8,4,7,6,3]) == [2, 3, 4, 6, 7, 8]
def emptymap = [:]
assert emptymap instanceof Map
mymap = ['a.b':1] // 带符号的key用引号定界
assert mymap.'a.b' == 1
store = ''
mymap.each {key, value -> // 闭包带2个参,自动配对kv
store += key
store += value
}
assert store.contains('a.b1')
6,面向对象
// SomeClass.groovy
class SomeClass {
static main(argv) {
def some = new SomeClass()
some.publicVoidMethod()
assert 'hi' == some.publicUntypedMethod()
combinedMethod()
}
void publicVoidMethod(){}
def publicUntypedMethod() {
return 'hi'
}
protected static final void combinedMethod () {}
}
========分割线 结束于 2014-12-8 ========
本来还想补充《Groovy入门经典》的部分,实在没空,以上这些基本够用,除了对象部分有点不足,后期coding在慢慢体验动态脚本语言的优劣,后面准备攻略Grails