Groovy

2018-02-24 15:18 更新

X分鐘速成Y

其中 Y=Groovy

源代碼下載:?learngroovy-cn.groovy

Groovy - Java平臺的動態(tài)語言。了解更多。

/*
  安裝:

  1) 安裝 GVM - http://gvmtool.net/
  2) 安裝 Groovy: gvm install groovy
  3) 啟動 groovy 控制臺,鍵入: groovyConsole

*/

//  雙斜線開始的是單行注釋
/*
像這樣的是多行注釋
*/

// Hello World
println "Hello world!"

/*
  變量:

  可以給變量賦值,以便稍后使用
*/

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

/*
  集合和映射
*/

//創(chuàng)建一個空的列表
def technologies = []

/*** 往列表中增加一個元素 ***/

// 和Java一樣
technologies.add("Grails")

// 左移添加,返回該列表
technologies << "Groovy"

// 增加多個元素
technologies.addAll(["Gradle","Griffon"])

/*** 從列表中刪除元素 ***/

// 和Java一樣
technologies.remove("Griffon")

// 減號也行
technologies = technologies - 'Grails'

/*** 遍歷列表 ***/

// 遍歷列表中的元素
technologies.each { println "Technology: $it"}
technologies.eachWithIndex { it, i -> println "$i: $it"}

/*** 檢查列表內(nèi)容 ***/

//判斷列表是否包含某元素,返回boolean
contained = technologies.contains( 'Groovy' )

// 或
contained = 'Groovy' in technologies

// 檢查多個元素
technologies.containsAll(['Groovy','Grails'])

/*** 列表排序 ***/

// 排序列表(修改原列表)
technologies.sort()

// 要想不修改原列表,可以這樣:
sortedTechnologies = technologies.sort( false )

/*** 列表操作 ***/

//替換列表元素
Collections.replaceAll(technologies, 'Gradle', 'gradle')

//打亂列表
Collections.shuffle(technologies, new Random())

//清空列表
technologies.clear()

//創(chuàng)建空的映射
def devMap = [:]

//增加值
devMap = ['name':'Roberto', 'framework':'Grails', 'language':'Groovy']
devMap.put('lastName','Perez')

//遍歷映射元素
devMap.each { println "$it.key: $it.value" }
devMap.eachWithIndex { it, i -> println "$i: $it"}

//判斷映射是否包含某鍵
assert devMap.containsKey('name')

//判斷映射是否包含某值
assert devMap.containsValue('Roberto')

//取得映射所有的鍵
println devMap.keySet()

//取得映射所有的值
println devMap.values()

/*
  Groovy Beans

  GroovyBeans 是 JavaBeans,但使用了更簡單的語法

  Groovy 被編譯為字節(jié)碼時,遵循下列規(guī)則。

    * 如果一個名字聲明時帶有訪問修飾符(public, private, 或者 protected),
      則會生成一個字段(field)。

    * 名字聲明時沒有訪問修飾符,則會生成一個帶有public getter和setter的
      private字段,即屬性(property)。

    * 如果一個屬性聲明為final,則會創(chuàng)建一個final的private字段,但不會生成setter。

    * 可以聲明一個屬性的同時定義自己的getter和setter。

    * 可以聲明具有相同名字的屬性和字段,該屬性會使用該字段。

    * 如果要定義private或protected屬性,必須提供聲明為private或protected的getter
      和setter。

    * 如果使用顯式或隱式的 this(例如 this.foo, 或者 foo)訪問類的在編譯時定義的屬性,
      Groovy會直接訪問對應字段,而不是使用getter或者setter

    * 如果使用顯式或隱式的 foo 訪問一個不存在的屬性,Groovy會通過元類(meta class)
      訪問它,這可能導致運行時錯誤。

*/

class Foo {
    // 只讀屬性
    final String name = "Roberto"

    // 只讀屬性,有public getter和protected setter
    String language
    protected void setLanguage(String language) { this.language = language }

    // 動態(tài)類型屬性
    def lastName
}

/*
  邏輯分支和循環(huán)
*/

//Groovy支持常見的if - else語法
def x = 3

if(x==1) {
    println "One"
} else if(x==2) {
    println "Two"
} else {
    println "X greater than Two"
}

//Groovy也支持三元運算符
def y = 10
def x = (y > 1) ? "worked" : "failed"
assert x == "worked"

//for循環(huán)
//使用區(qū)間(range)遍歷
def x = 0
for (i in 0 .. 30) {
    x += i
}

//遍歷列表
x = 0
for( i in [5,3,2,1] ) {
    x += i
}

//遍歷數(shù)組
array = (0..20).toArray()
x = 0
for (i in array) {
    x += i
}

//遍歷映射
def map = ['name':'Roberto', 'framework':'Grails', 'language':'Groovy']
x = 0
for ( e in map ) {
    x += e.value
}

/*
  運算符

  在Groovy中以下常用運算符支持重載:
  http://www.groovy-lang.org/operators.html#Operator-Overloading

  實用的groovy運算符
*/
//展開(spread)運算符:對聚合對象的所有元素施加操作
def technologies = ['Groovy','Grails','Gradle']
technologies*.toUpperCase() // 相當于 technologies.collect { it?.toUpperCase() }

//安全導航(safe navigation)運算符:用來避免NullPointerException
def user = User.get(1)
def username = user?.username

/*
  閉包
  Groovy閉包好比代碼塊或者方法指針,它是一段代碼定義,可以以后執(zhí)行。

  更多信息見:http://www.groovy-lang.org/closures.html
*/
//例子:
def clos = { println "Hello World!" }

println "Executing the Closure:"
clos()

//傳參數(shù)給閉包
def sum = { a, b -> println a+b }
sum(2,4)

//閉包可以引用參數(shù)列表以外的變量
def x = 5
def multiplyBy = { num -> num * x }
println multiplyBy(10)

// 只有一個參數(shù)的閉包可以省略參數(shù)的定義
def clos = { print it }
clos( "hi" )

/*
  Groovy可以記憶閉包結(jié)果 [1][2][3]
*/
def cl = {a, b ->
    sleep(3000) // 模擬費時操作
    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

  Expando類是一種動態(tài)bean類,可以給它的實例添加屬性和添加閉包作為方法

  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)

/*
  元編程(MOP)
*/

//使用ExpandoMetaClass增加行為
String.metaClass.testAdd = {
    println "we added this"
}

String x = "test"
x?.testAdd()

//攔截方法調(diào)用
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)

//Groovy支持propertyMissing,來處理屬性解析嘗試
class Foo {
   def propertyMissing(String name) { name }
}
def f = new Foo()

assertEquals "boo", f.boo

/*
  類型檢查和靜態(tài)編譯
  Groovy天生是并將永遠是一門動態(tài)語言,但也支持類型檢查和靜態(tài)編譯

  更多: http://www.infoq.com/articles/new-groovy-20
*/
//類型檢查
import groovy.transform.TypeChecked

void testMethod() {}

@TypeChecked
void test() {
    testMeethod()

    def name = "Roberto"

    println naameee

}

//另一例子
import groovy.transform.TypeChecked

@TypeChecked
Integer test() {
    Integer num = "1"

    Integer[] numbers = [1,2,3,4]

    Date date = numbers[1]

    return "Test"

}

//靜態(tài)編譯例子
import groovy.transform.CompileStatic

@CompileStatic
int sum(int x, int y) {
    x + y
}

assert sum(2,5) == 7

進階資源

Groovy文檔

Groovy web console

加入Groovy用戶組

圖書

[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

以上內(nèi)容是否對您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號
微信公眾號

編程獅公眾號