learnxinyminutes-docs/zh-cn/groovy-cn.html.markdown

423 lines
8.5 KiB
Groovy
Raw Normal View History

2015-06-18 14:20:30 +00:00
---
language: Groovy
2015-06-19 02:58:39 +00:00
filename: learngroovy-cn.groovy
2015-06-18 14:20:30 +00:00
contributors:
- ["Roberto Pérez Alcolea", "http://github.com/rpalcolea"]
2015-06-19 02:58:39 +00:00
translators:
- ["Todd Gao", "http://github.com/7c00"]
lang: zh-cn
2015-06-18 14:20:30 +00:00
---
2015-06-19 02:58:39 +00:00
Groovy - Java平台的动态语言[](http://www.groovy-lang.org/)
2015-06-18 14:20:30 +00:00
```groovy
/*
2015-06-19 02:58:39 +00:00
2015-06-18 14:20:30 +00:00
2015-06-19 02:58:39 +00:00
1) GVM - http://gvmtool.net/
2) Groovy gvm install groovy
3) groovy groovyConsole
2015-06-18 14:20:30 +00:00
*/
2015-06-19 02:58:39 +00:00
// 双斜线开始的是单行注释
2015-06-18 14:20:30 +00:00
/*
2015-06-19 02:58:39 +00:00
2015-06-18 14:20:30 +00:00
*/
// Hello World
println "Hello world!"
/*
2015-06-19 02:58:39 +00:00
2015-06-18 14:20:30 +00:00
2015-06-19 04:16:41 +00:00
便使
2015-06-18 14:20:30 +00:00
*/
def x = 1
println x
x = new java.util.Date()
println x
x = -3.1499392
println x
x = false
println x
x = "Groovy!"
println x
/*
2015-06-19 04:16:41 +00:00
2015-06-18 14:20:30 +00:00
*/
2015-06-19 02:58:39 +00:00
//创建一个空的列表
2015-06-18 14:20:30 +00:00
def technologies = []
2015-06-19 02:58:39 +00:00
/*** 往列表中增加一个元素 ***/
2015-06-18 14:20:30 +00:00
2015-06-19 02:58:39 +00:00
// 和Java一样
2015-06-18 14:20:30 +00:00
technologies.add("Grails")
2015-06-19 02:58:39 +00:00
// 左移添加,返回该列表
2015-06-18 14:20:30 +00:00
technologies << "Groovy"
2015-06-19 02:58:39 +00:00
// 增加多个元素
2015-06-18 14:20:30 +00:00
technologies.addAll(["Gradle","Griffon"])
2015-06-19 02:58:39 +00:00
/*** 从列表中删除元素 ***/
2015-06-18 14:20:30 +00:00
2015-06-19 02:58:39 +00:00
// 和Java一样
2015-06-18 14:20:30 +00:00
technologies.remove("Griffon")
2015-06-19 04:16:41 +00:00
// 减号也行
2015-06-18 14:20:30 +00:00
technologies = technologies - 'Grails'
2015-06-19 02:58:39 +00:00
/*** 遍历列表 ***/
2015-06-18 14:20:30 +00:00
2015-06-19 02:58:39 +00:00
// 遍历列表中的元素
2015-06-18 14:20:30 +00:00
technologies.each { println "Technology: $it"}
technologies.eachWithIndex { it, i -> println "$i: $it"}
2015-06-19 02:58:39 +00:00
/*** 检查列表内容 ***/
2015-06-18 14:20:30 +00:00
2015-06-19 02:58:39 +00:00
//判断列表是否包含某元素返回boolean
2015-06-18 14:20:30 +00:00
contained = technologies.contains( 'Groovy' )
2015-06-19 02:58:39 +00:00
// 或
2015-06-18 14:20:30 +00:00
contained = 'Groovy' in technologies
2015-06-19 02:58:39 +00:00
// 检查多个元素
2015-06-18 14:20:30 +00:00
technologies.containsAll(['Groovy','Grails'])
2015-06-19 04:16:41 +00:00
/*** 列表排序 ***/
2015-06-18 14:20:30 +00:00
2015-06-19 02:58:39 +00:00
// 排序列表(修改原列表)
2015-06-18 14:20:30 +00:00
technologies.sort()
2015-06-19 02:58:39 +00:00
// 要想不修改原列表,可以这样:
2015-06-18 14:20:30 +00:00
sortedTechnologies = technologies.sort( false )
2015-06-19 04:16:41 +00:00
/*** 列表操作 ***/
2015-06-18 14:20:30 +00:00
2015-06-19 02:58:39 +00:00
//替换列表元素
2015-06-18 14:20:30 +00:00
Collections.replaceAll(technologies, 'Gradle', 'gradle')
2015-06-19 02:58:39 +00:00
//打乱列表
2015-06-18 14:20:30 +00:00
Collections.shuffle(technologies, new Random())
2015-06-19 02:58:39 +00:00
//清空列表
2015-06-18 14:20:30 +00:00
technologies.clear()
2015-06-19 04:16:41 +00:00
//创建空的映射
2015-06-18 14:20:30 +00:00
def devMap = [:]
2015-06-19 02:58:39 +00:00
//增加值
2015-06-18 14:20:30 +00:00
devMap = ['name':'Roberto', 'framework':'Grails', 'language':'Groovy']
devMap.put('lastName','Perez')
2015-06-19 04:16:41 +00:00
//遍历映射元素
2015-06-18 14:20:30 +00:00
devMap.each { println "$it.key: $it.value" }
devMap.eachWithIndex { it, i -> println "$i: $it"}
2015-06-19 04:16:41 +00:00
//判断映射是否包含某键
2015-06-18 14:20:30 +00:00
assert devMap.containsKey('name')
2015-06-19 04:16:41 +00:00
//判断映射是否包含某值
2015-06-18 14:20:30 +00:00
assert devMap.containsValue('Roberto')
2015-06-19 04:16:41 +00:00
//取得映射所有的键
2015-06-18 14:20:30 +00:00
println devMap.keySet()
2015-06-19 04:16:41 +00:00
//取得映射所有的值
2015-06-18 14:20:30 +00:00
println devMap.values()
/*
Groovy Beans
2015-06-19 02:58:39 +00:00
GroovyBeans JavaBeans使
2015-06-18 14:20:30 +00:00
2015-06-19 02:58:39 +00:00
Groovy
2015-06-18 14:20:30 +00:00
2015-06-19 02:58:39 +00:00
* 访public, private, protected
field
2015-06-18 14:20:30 +00:00
2015-06-19 02:58:39 +00:00
* 访public getter和setter的
private字段property
2015-06-18 14:20:30 +00:00
2015-06-19 02:58:39 +00:00
* finalfinal的private字段setter
2015-06-18 14:20:30 +00:00
2015-06-19 02:58:39 +00:00
* getter和setter
2015-06-18 14:20:30 +00:00
2015-06-19 02:58:39 +00:00
* 使
2015-06-18 14:20:30 +00:00
2015-06-19 02:58:39 +00:00
* private或protected属性private或protected的getter
setter
2015-06-18 14:20:30 +00:00
2015-06-19 02:58:39 +00:00
* 使 this this.foo, foo访
Groovy会直接访问对应字段使getter或者setter
2015-06-18 14:20:30 +00:00
2015-06-19 02:58:39 +00:00
* 使 foo 访Groovy会通过元类meta class
访
2015-06-18 14:20:30 +00:00
*/
class Foo {
2015-06-19 02:58:39 +00:00
// 只读属性
2015-06-18 14:20:30 +00:00
final String name = "Roberto"
2015-06-19 02:58:39 +00:00
// 只读属性有public getter和protected setter
2015-06-18 14:20:30 +00:00
String language
protected void setLanguage(String language) { this.language = language }
2015-06-19 02:58:39 +00:00
// 动态类型属性
2015-06-18 14:20:30 +00:00
def lastName
}
/*
2015-06-19 02:58:39 +00:00
2015-06-18 14:20:30 +00:00
*/
2015-06-19 02:58:39 +00:00
//Groovy支持常见的if - else语法
2015-06-18 14:20:30 +00:00
def x = 3
if(x==1) {
println "One"
} else if(x==2) {
println "Two"
} else {
println "X greater than Two"
}
2015-06-19 02:58:39 +00:00
//Groovy也支持三元运算符
2015-06-18 14:20:30 +00:00
def y = 10
def x = (y > 1) ? "worked" : "failed"
assert x == "worked"
2015-06-19 02:58:39 +00:00
//for循环
//使用区间range遍历
2015-06-18 14:20:30 +00:00
def x = 0
for (i in 0 .. 30) {
x += i
}
2015-06-19 02:58:39 +00:00
//遍历列表
2015-06-18 14:20:30 +00:00
x = 0
for( i in [5,3,2,1] ) {
x += i
}
2015-06-19 02:58:39 +00:00
//遍历数组
2015-06-18 14:20:30 +00:00
array = (0..20).toArray()
x = 0
for (i in array) {
x += i
}
2015-06-19 04:16:41 +00:00
//遍历映射
2015-06-18 14:20:30 +00:00
def map = ['name':'Roberto', 'framework':'Grails', 'language':'Groovy']
x = ""
2015-06-18 14:20:30 +00:00
for ( e in map ) {
x += e.value
x += " "
2015-06-18 14:20:30 +00:00
}
assert x.equals("Roberto Grails Groovy ")
2015-06-18 14:20:30 +00:00
/*
2015-06-19 02:58:39 +00:00
2015-06-18 14:20:30 +00:00
2015-06-19 04:16:41 +00:00
Groovy中以下常用运算符支持重载
2015-06-18 14:20:30 +00:00
http://www.groovy-lang.org/operators.html#Operator-Overloading
2015-06-19 02:58:39 +00:00
groovy运算符
2015-06-18 14:20:30 +00:00
*/
2015-06-19 02:58:39 +00:00
//展开spread运算符对聚合对象的所有元素施加操作
2015-06-18 14:20:30 +00:00
def technologies = ['Groovy','Grails','Gradle']
2015-06-19 02:58:39 +00:00
technologies*.toUpperCase() // 相当于 technologies.collect { it?.toUpperCase() }
2015-06-18 14:20:30 +00:00
2015-06-19 02:58:39 +00:00
//安全导航safe navigation运算符用来避免NullPointerException
2015-06-18 14:20:30 +00:00
def user = User.get(1)
def username = user?.username
/*
2015-06-19 02:58:39 +00:00
2015-06-19 04:16:41 +00:00
Groovy闭包好比代码块或者方法指针
2015-06-18 14:20:30 +00:00
2015-06-19 02:58:39 +00:00
http://www.groovy-lang.org/closures.html
2015-06-18 14:20:30 +00:00
*/
2015-06-19 02:58:39 +00:00
//例子:
2015-06-18 14:20:30 +00:00
def clos = { println "Hello World!" }
println "Executing the Closure:"
clos()
2015-06-19 02:58:39 +00:00
//传参数给闭包
2015-06-18 14:20:30 +00:00
def sum = { a, b -> println a+b }
sum(2,4)
2015-06-19 02:58:39 +00:00
//闭包可以引用参数列表以外的变量
2015-06-18 14:20:30 +00:00
def x = 5
def multiplyBy = { num -> num * x }
println multiplyBy(10)
2015-06-19 02:58:39 +00:00
// 只有一个参数的闭包可以省略参数的定义
2015-06-18 14:20:30 +00:00
def clos = { print it }
clos( "hi" )
/*
2015-06-19 02:58:39 +00:00
Groovy可以记忆闭包结果 [1][2][3]
2015-06-18 14:20:30 +00:00
*/
def cl = {a, b ->
2015-06-19 02:58:39 +00:00
sleep(3000) // 模拟费时操作
2015-06-18 14:20:30 +00:00
a + b
}
mem = cl.memoize()
def callClosure(a, b) {
def start = System.currentTimeMillis()
mem(a, b)
println "Inputs(a = $a, b = $b) - took ${System.currentTimeMillis() - start} msecs."
}
callClosure(1, 2)
callClosure(1, 2)
callClosure(2, 3)
callClosure(2, 3)
callClosure(3, 4)
callClosure(3, 4)
callClosure(1, 2)
callClosure(2, 3)
callClosure(3, 4)
/*
Expando
2015-06-19 02:58:39 +00:00
Expando类是一种动态bean类
2015-06-18 14:20:30 +00:00
http://mrhaki.blogspot.mx/2009/10/groovy-goodness-expando-as-dynamic-bean.html
*/
def user = new Expando(name:"Roberto")
assert 'Roberto' == user.name
user.lastName = 'Pérez'
assert 'Pérez' == user.lastName
user.showInfo = { out ->
out << "Name: $name"
out << ", Last name: $lastName"
}
def sw = new StringWriter()
println user.showInfo(sw)
/*
2015-06-19 02:58:39 +00:00
(MOP)
2015-06-18 14:20:30 +00:00
*/
2015-06-19 02:58:39 +00:00
//使用ExpandoMetaClass增加行为
2015-06-18 14:20:30 +00:00
String.metaClass.testAdd = {
println "we added this"
}
String x = "test"
x?.testAdd()
2015-06-19 04:16:41 +00:00
//拦截方法调用
2015-06-18 14:20:30 +00:00
class Test implements GroovyInterceptable {
def sum(Integer x, Integer y) { x + y }
def invokeMethod(String name, args) {
System.out.println "Invoke method $name with args: $args"
}
}
def test = new Test()
test?.sum(2,3)
test?.multiply(2,3)
2015-06-19 02:58:39 +00:00
//Groovy支持propertyMissing来处理属性解析尝试
2015-06-18 14:20:30 +00:00
class Foo {
def propertyMissing(String name) { name }
}
def f = new Foo()
assertEquals "boo", f.boo
/*
2015-06-19 02:58:39 +00:00
2015-06-19 04:16:41 +00:00
Groovy天生是并将永远是一门动态语言
2015-06-18 14:20:30 +00:00
2015-06-19 02:58:39 +00:00
http://www.infoq.com/articles/new-groovy-20
2015-06-18 14:20:30 +00:00
*/
2015-06-19 02:58:39 +00:00
//类型检查
2015-06-18 14:20:30 +00:00
import groovy.transform.TypeChecked
void testMethod() {}
@TypeChecked
void test() {
testMeethod()
def name = "Roberto"
println naameee
}
2015-06-19 02:58:39 +00:00
//另一例子
2015-06-18 14:20:30 +00:00
import groovy.transform.TypeChecked
@TypeChecked
Integer test() {
Integer num = "1"
Integer[] numbers = [1,2,3,4]
Date date = numbers[1]
return "Test"
}
2015-06-19 02:58:39 +00:00
//静态编译例子
2015-06-18 14:20:30 +00:00
import groovy.transform.CompileStatic
@CompileStatic
int sum(int x, int y) {
x + y
}
assert sum(2,5) == 7
```
2015-06-19 02:58:39 +00:00
##
2015-06-18 14:20:30 +00:00
2015-06-19 02:58:39 +00:00
[Groovy文档](http://www.groovy-lang.org/documentation.html)
2015-06-18 14:20:30 +00:00
[Groovy web console](http://groovyconsole.appspot.com/)
2015-06-19 02:58:39 +00:00
[Groovy用户组](http://www.groovy-lang.org/usergroups.html)
2015-06-18 14:20:30 +00:00
2015-06-19 02:58:39 +00:00
##
2015-06-18 14:20:30 +00:00
* [Groovy Goodness] (https://leanpub.com/groovy-goodness-notebook)
* [Groovy in Action] (http://manning.com/koenig2/)
* [Programming Groovy 2: Dynamic Productivity for the Java Developer] (http://shop.oreilly.com/product/9781937785307.do)
[1] http://roshandawrani.wordpress.com/2010/10/18/groovy-new-feature-closures-can-now-memorize-their-results/
[2] http://www.solutionsiq.com/resources/agileiq-blog/bid/72880/Programming-with-Groovy-Trampoline-and-Memoize
[3] http://mrhaki.blogspot.mx/2011/05/groovy-goodness-cache-closure-results.html