Gradle學習筆記之Groovy
[TOC]
Gradle 的核心功能是由Java實現. 在這些功能之上, 有一個使用動態編程語言Groovy編寫的領域特定語言(DSL). Gradle的構建腳本build.gradle和setting.gradle都是可執行的Groovy腳本(不過它們不可以在Groovy運行時環境下運行, 由於上述.gradle文件都需要調用gradle的api運行且後綴不是.groovy). 下面通過與Java對比, 簡單介紹小於Gradle相關的Groovy語言知識.
1. 什麼是Groovy
Groovy是一個基於Java虛擬機的動態語言。這門動態語言擁有類似Python、Ruby和Smalltalk中的一些特性,可以作為Java平台的腳本語言使用。Groovy的語法與Java非常相似,以至於多數的Java代碼也是正確的Groovy代碼.
- Java開發者提供了 現代最流行的編程語言特性,而且學習成本很低。
- 支持DSL(Domain Specific Languages領域定義語言)和其它簡潔的語法,讓你的代碼變得易於閱讀和維護.
- 無縫集成所有已經存在的 Java對象和類庫.
- 接編譯成Java位元組碼,這樣可以在任何使用Java的地方 使用Groovy。
2. Java VS Groovy
下面先給出Groovy運行環境下含義相同的Java和Groovy 代碼片, 然後在說明二者的區別
java
public class Me {
private String name;
public Me(String name) { this.name = name; }
public String getName { return name; }
public void setName(String name) { this.name = name; }
}
groovy
class Me {
String name
public Me(String name) { this.name = name}
}
從上面我們可以看到Groovy版本更加簡潔,下面給出Groovy相對於Java的特點:
- 表達式後面的分號
;
是可選的; - 每個
類
,構造器
,方法
訪問屬性默認是public的 - 方法體中的最後一個表達式的值被作為返回值, 這意味著
return
語句是可選的; - Groovy編譯器自動加上getter/setter方法, 不需要自己手動添加;
- 類的屬性可以通過點號
.
獲取與賦值, 底層是通過調用自動生成的getter/setter方法. - Groovy中用
==
比較兩個實例, 底層調用的是equals方法, 這個操作也可以避免可能的空指針異常.
3. Groovy 高級特性
3.1 可選類型定義
作為動態語言,groovy中所有的變數都是對象
,在聲明一個變數時,groovy不要求強制類型聲明,僅僅要求變數名前使用關鍵字def
, def關鍵字作為java.lang.Object的一個佔位符, 在運行時確定類型.
//assert用於斷言檢查 )
def var = 1
assert var.class == java.lang.Integer
var = "bupt"
assert var.class == java.lang.String
3.2 可選的括弧
在Groovy中如果方法簽名需要至少一個參數, 則方法調用可以省略括弧.
def callMe(name) {
new Me(name)
}
callMe("faith")
callMe "faith"
println("we could not live without faith!")
println "we could not live without faith!"
3.3 字元串
在Groovy中, 有三種不同方式定義字元串. 帶單引號"
的通常創建等效於Java的String類型; 第二種和Java相同用雙引號"
包起來, 跨行的字元串用三個雙引號包起來"""
.
幾點說明:
- 跟java一樣,可以使用
+
號連接字元串; - Groovy中帶雙引號的字元串可以插值帶變數或者表達式中, 通過
$
和花括弧{}
表示, 運行時, Groovy計算表達式並組成字元串.這種字元串在Groovy中叫做GString. 通過下面的例子s4
s5
也能看到和單引號的不同.
def s1 = "bupt"
def s2 = "bupt"
def s3 = """b
u
p
t
"""
def s4 = "hello "+
"${s1}"
def s5 = "hello "+
"${s1}"
println s1
println s2
println s3
println s4
輸出:
bupt
bupt
b
u
p
t
hello bupt
hello ${s1}
3.4 命名參數
Groovy 中提供了一個減少輸入的特性叫做命名參數(Named Parameter)。GroovyBean 可以通過在構造器調用中傳遞冒號隔開的屬性名稱和值進行構建。如:
class Me {
String name
}
Me me = new Me(name: "faith")
println me.name
me.name = "bupt"
println me.name
輸出:
faith
bupt
從外部表現上好像是先調用了空構造方法,然後是相應的 setter 方法進行設值。因此,我們所直接想像的應該相當於下列 Java 代碼:
Me me = new Me;
me.setName("faith");
3.5 閉包
在介紹閉包前,先來講幾個Groovy中代碼塊的一些特性。
3.5.1 代碼塊- groovy的變數作用域和java相似,代碼塊內部聲明的變數不能被外部訪問調用。
- 對於Groovy Script, 用def定義的變數對binding.variables不可見。沒有def等任何定義的可被binding.variable.參數名所訪問。
- 對於第一條規則,有個例外,當變數沒有def等任何定義時,該變數全局有效.
- 代碼塊可以嵌套,比如try代碼塊,這和Java是一樣的。
try{
h = 9
assert binding.variables.h == 9
}
assert h == 9
assert binding.variables.h == 9
3.5.2 閉包簡介
閉包是類型為groovy.lang.Closure用花括弧{}
括起來的代碼塊. 類似於Python的lambda表達式, 閉包可以被賦值給變數, 作為參數傳遞給方法, 並且像普通方法一樣調用.
看起來,閉包類似於方法,需要定義參數和要執行的語句,它也可以通過名稱被調用。然而閉包對象可以作為參數傳遞. 其次,閉包也可以不命名(當然作為代價,只能在定義閉包時執行一次)
3.5.3 閉包參數1.顯示參數閉包:
閉包的參數聲明寫在『->』符號前,調用閉包的的標準寫法是:閉包名.call(閉包參數)。
def toTriple = {n -> n * 3}
assert toTriple.call( 5 ) == 15
2.隱士參數閉包:
對於單一存在的參數it可以不用聲明,直接使用it,it在Groovy中有著特殊的意義;當且僅當閉包中有且僅有一個參數,且不顯示聲明,it具有唯一參數引用的作用;如果閉包c是無參數閉包,那麼它的標準調用方法是c.call,它的簡潔調用方法是c。
c = { it*3 }
assert c( "run" ) == "runrunrun"
def a = "coffee"
def c = {
def b = "tea"
a + " and " + b
}
assert c == "coffee and tea"
3.閉包隱含參數
參數 | 說明 |
---|---|
it | 默認的參數名,調用是如果沒有傳參數,it為null |
this | 跟Java一樣,是定義閉包所在類的一個引用,不管有多少層閉包嵌套,this指向的都是最上層的類。 |
owner | 封閉閉包的對象(如果只有一層閉包就是this,如果有多層閉包嵌套就是含有此閉包的上層閉包) |
delegate | 預設值是owner,但是可以改變,後面詳說。 |
4.閉包中的參數名不能重複,it除外。
def name= "cup"
def c={ name-> println (name) }
//a compile error when uncommented:
//current scope already contains name "name"
c= { def d= { 2 * it }; 3 * d(it) }
assert c(5) == 30
5.閉包是可嵌套的
def gcd //predefine closure name
gcd={ m,n-> m%n==0? n: gcd(n,m%n) }
assert gcd( 28, 35 ) == 7
3.5.4 閉包返回值
閉包總是會有一個返回值,返回值是閉包的最後一行語句,不論該語句是否冠名return關鍵字。如果閉包最後一句沒有值, 返回 null;
3.5.5 賦值與調用賦值: 閉包賦值給一個變數,和變數與變數間的賦值一致。
def c
try{
def a = "sugar"
c = { a } //a closure always returns its only value
}
assert c == "sugar"
def d = c //we can also assign the closure to another variable
assert d == "sugar"
調用: 調用閉包的方法等於創建一個閉包實例。對於相同閉包創建出來的不同實例,他們的對象是不同的。
c = { def e = { "milk" }; e }
d = c
assert c == d
v1 = c
v2 = c
assert v1 != v2
3.5.6 閉包委託
delegate委託的用法 delegate委託在是一種常用設計模式,但在java中實現相對比較繁瑣,groovy直接在GroovyObject中已經實現了delegate模式,所以在groovy中應用delegate很方便。
下面看一個狗爸爸讓老貓幫忙照看他的狗兒子玩遊戲的例子:
class Dog{
def play = {
"wang wang!"
}
def childmind = {
println delegate.play;
}
}
class Cat {
def play = {"mi mi !"}
}
def dog = new Dog
def cat = new Cat
dog.childmind
dog.childmind.delegate = cat;
dog.childmind
3.6 集合
Groovy支持最常見的兩個java集合: java.util.Collection和java.util.Map。
3.6.1 Collection//1、定義一個集合
def collect = ["a","b","c"]
//2、給集合增加元素
collect.add(1);
collect << "come on";
collect[collect.size()] = 100.0
//3、集合索引
println collect[collect.size()-1]
println collect
println collect.size
//4、負索引
println collect[-1] //索引其倒數第1個元素
println collect[-2] //索引其倒數第2個元素
//5、集合運算:
collect=collect+5 //在集合中添加元素5
println collect[collect.size()-1]
collect=collect-"a" //在集合中減去元素a(第1個)
println collect[0] //現在第1個元素變成b了
//6、往集合中添加另一個集合或刪除一個集合:
collect=collect-collect[0..4] //把集合中的前5個元素去掉
println collect[0] //現在集合中僅有一個元素,即原來的最後一個元素
println collect[-1] //也可以用負索引,證明最後一個元素就是第一個元素
3.6.2 Map
Map是「鍵-值」對的集合,在groovy中,鍵不一定是String,可以是任何對象(實際上Groovy中的Map就是java.util.LinkedHashMap)。
//1、定義一個Map:
def map = ["name":"john","age":14,"sex":"boy"]
println map
//2、添加項:
map = map+["weight":25] //添加john的體重
map.put("length",1.27) //添加john的身高
map.father="Keller" //添加john的父親
println map
//3、兩種方式檢索值:
println map["father"] //通過key作為下標索引
println map.length //通過key作為成員名索引
閉包中最常見的應用是對集合進行迭代,下面定義了3個閉包對map進行了迭代:
def map = ["name":"john","age":14,"sex":"boy"]
map.each(
{key,value-> // key,value兩個參數用於接受每個元素的鍵/值
println "$key:$value"})
map.each{println it} //it是一個關鍵字,代表map集合的每個元素
map.each({ println it.getKey+"-->"+it.getValue})
列印如下:
name:john
age:14
sex:boy
name=john
age=14
sex=boy
name-->john
age-->14
sex-->boy
參考:
- Groovy基礎——Closure(閉包)詳解
- Unmi 學習 Groovy 之命名參數
- Groovy語言學習:groovy語言簡介及基本語法
- <gradle實戰>


※你猜這個題輸出啥?——java基礎概念
※C基礎:.NET環境下WebConfig的加密
※從 JavaScript 到 TypeScript
※簡單RPC框架-業務線程池
TAG:達人科技 |
※學習筆記之TensorFlow
※論文筆記:Sequence Generative Adversarial Nets with Policy Gradient
※微軟機器學習Machine Learning Studio學習筆記
※GCC工作筆記 Google Patent
※【Code筆記本】Valid Parentheses
※筆記應用GoodNotes將推出macOS版本,基於Project Catalyst框架
※讀書筆記:Eating for Cognitive Power
※《Relation Networks for Object Detection》論文筆記
※Georgina 曼谷咻咻筆記
※論文筆記:Fraternal Dropout
※Google新款筆記本代號Atlas:運行Chrome OS
※論文筆記:Attention is All You Need
※Spring Cloud Feign使用筆記
※Gartner:微軟Surface可以叫筆記本,iPad不行
※Gartner:微軟Surface可以叫筆記本,iPad不行
※Chromebook筆記本將支持Assistant助手
※Machine Learning Yearning 要點筆記
※《The innovators》讀書筆記
※Ahmedabad,India攝影筆記
※iBall推出CompBook Premio筆記本電腦