as、assert、break、case、catch、class、const、continue、def、default、do、else、enum、extends、false、finally、for、goto、if、implements、import、in、instanceof、interface、new、null、package、return、super、switch、this、throw、throws、trait、true、try、while
複製代碼
若是當前這個函數是 Groovy API 或者 Gradle API 中比較經常使用的,好比 println,就能夠不帶括號。不然仍是帶括號。否則,Groovy 可能會把屬性和函數調用混淆。java
// 輸出 ok
def num = 5.21
switch (num) {
case [5.21, 4, "list"]:
return "ok"
break
default:
break
}
複製代碼
可是,其實 Groovy 中並無基本類型,Groovy 做爲動態語言, 在它的世界中,全部事物都是對象,就如 Python、Kotlin 同樣:全部的基本類型都是屬於對象類型。android
若是這個變量就是用於當前類或文件,而不會用於其它類或應用模塊,那麼,建議使用 def 類型,由於在這種場景下弱類型就足夠了。 可是,若是你這個類或變量要用於其它模塊的,建議不要使用 def,仍是應該使用 Java 中的那種強類型定義方式,由於使用強類型的定義方式,它不能動態轉換爲其它類型,它可以保證外界傳遞進來的值必定是正確的。編程
task groovyString{
doLast{
def name="abc"
println '單引號的變量計算:${name}'
println "雙引號的變量計算:${name}"
println "$name" //只有一個變量時可省略大括號
println "${1+2*3}"
}
}
gradle groovyString
> Task :groovyString
單引號的變量計算:${name}
雙引號的變量計算:abc
abc
7
複製代碼
Groovy 中還新增了一個 GString 類型(當雙引號種包含表達式運算時,打印其類型就是GString),編譯器能夠幫咱們自動在 String 和 GString 之間相互轉換,咱們在編寫的時候並不須要太過關注它們的區別。bash
task printList {
def numList=[10,11,12,13,14]
println numList.getClass().name
println numList[0]
println numList[1]
println numList[-1]
println numList[1..3]
numList.each{
println it
}
}
$ gradle printList
> Configure project :
java.util.ArrayList
10
11
14
[11, 12, 13]
10
11
12
13
14
task printMap{
def map1=['width':1080,'height':1920]
println map1.getClass().name
println map1['width']
println map1.height
map1.each{
println "key=${it.key}, value=${it.value}"
}
}
$ gradle printMap
> Configure project :
java.util.LinkedHashMap
1080
1920
key=width, value=1080
key=height, value=1920
複製代碼
task printMethodReturn{
def add1=method1 1,2
def add2=method1 6,4
println "add1=$add1,add2=$add2"
}
def method1(int a,int b){
if(a>b)
a
else
b
}
$ gradle printMethodReturn
> Configure project :
add1=2,add2=6
複製代碼
task printEach{
def list=[11,12,13,14]
//下面幾種打印it寫法
list.each({println it})
list.each({
println it
})
//方法的最後一個參數是閉包能夠放到方法外面
list.each(){
println it
}
//方法能夠省略括號
list.each{
println it
}
}
複製代碼
若是不聲明 public/private 等訪問權限的話,Groovy 中類及其變量默認都是 public 的;閉包
task printJavaBean{
Person p=new Person()
println "name=$p.name"
p.name="bob"
println "name=$p.name"
println "age=$p.age"
}
class Person{
private String name
public int getAge(){
28
}
}
gradle printJavaBean
> Configure project :
name=null
name=bob
age=28
複製代碼
對於每個 Groovy 腳原本說,它都會生成一個 static void main 函數,main 函數中會調用一個 run 函數,腳本中的全部代碼則包含在 run 函數之中app
當咱們在 Groovy 腳本中定義一個變量時,因爲它其實是在 run 函數中建立的,因此腳本中的其它方法或其餘腳本是沒法訪問它的。這個時候,咱們須要使用 @Field 將當前變量標記爲成員變量jvm
import groovy.transform.Field;
@Field author = JinYang
複製代碼
相似lambda表達式函數
task helloClosure{
customEach{
println it
}
eachMap {k,v ->
println "$k is $v"
}
}
def customEach(closure){
for(int i in 1..10){
closure(i)
}
}
//向閉包傳參數
def eachMap(closure){
def map=['name':'zhangsan','age':18]
map.each{
closure(it.key,it.value)
}
}
複製代碼
groovy支持閉包方法的委託,其閉包有三個屬性thisObject,owner,delegate, 調用閉包方法時,由他們肯定使用哪一個對象來處理gradle
task helloDelegate{
new Delegate().test{
println "thisObject:${thisObject.getClass()}"
println "owner:${owner.getClass()}"
println "delegate:${delegate.getClass()}"
method1()
it.method1()
}
}
def method1(){
println "Context this:${this.getClass()} int root"
println "method1 in root"
}
class Delegate{
def method1(){
println "Delegate this:${this.getClass()} in Delegate"
println "method1 in Delegate"
}
def test(Closure<Delegate> closure){
closure(this)
}
}
$ gradle helloDelegate
thisObject:class build_d0vx8g4wj498jzsd4g4xes7j2
owner:class build_d0vx8g4wj498jzsd4g4xes7j2$_run_closure11
delegate:class build_d0vx8g4wj498jzsd4g4xes7j2$_run_closure11
Context this:class build_d0vx8g4wj498jzsd4g4xes7j2 int root
method1 in root
Delegate this:class Delegate in Delegate
method1 in Delegate
複製代碼
DSL中,好比Gradle,咱們通常指定delegate爲當前的it,這樣咱們在閉包內就能夠對該it進行配置,或調用其方法ui
task configClosure{
dog{
dogName="bob"
dogAge=7
dumpDog()
}
}
class Dog{
String dogName
int dogAge
def dumpDog(){
println "name is $dogName,age is $dogAge"
}
}
def dog(Closure<Dog> closure){
Dog d=new Dog()
closure.delegate=d
//委託模式優先
closure.setResolveStrategy(Closure.DELEGATE_FIRST)
closure(d)
}
複製代碼
領域特定語言,在專而不在全,如Gradle是基於groovy,專門解決自動化構建的DSL
task readLine{
def file =new File("./info.txt")
file.eachLine{ String oneLine ->
println oneLine
}
def text=file.getText()
println text
def text2=file.readLines()
println text2
file.eachLine{oneLine,lineNo ->
println "${lineNo} --> ${oneLine}"
}
}
$ gradle readLine -b file.gradle
> Configure project :
zhangsan
lisi
wangwu
zhaoliu
zhangsan
lisi
wangwu
zhaoliu
[zhangsan, lisi, wangwu, zhaoliu]
1 --> zhangsan
2 --> lisi
3 --> wangwu
4 --> zhaoliu
複製代碼
//操做 ism,最後記得關掉
def ism = targetFile.newInputStream()
// do sth
ism.close
//利用閉包來操做 inputStream,其功能更增強大,推薦使用這種寫法
targetFile.withInputStream{ ism ->
// 操做 ism,不用 close。Groovy 會自動替你 close
}
複製代碼
task writeFile{
def srcFile=new File('./info.txt')
def targetFile=new File('./copyInfo.txt')
targetFile.withOutputStream{ os->
srcFile.withInputStream{ ins->
//利用 OutputStream 的<<操做符重載,完成從 inputstream 到 OutputStream //的輸出
os << ins
}
}
}
複製代碼
task writeFile2{
try{
def srcFile=new File('./info.txt')
def targetFile=new File('./copyInfo.txt')
if(!targetFile.exists()){
targetFile.createNewFile()
}
srcFile.withReader{reader ->
def lines = reader.readLines()
targetFile.withWriter{writer ->
lines.each{line ->
writer.append(line + "\r\n")
}
}
}
return true
}catch(Exception e){
e.printStackTrace()
}
return false
}
複製代碼
此外,咱們也能夠經過 withObjectOutputStream/withObjectInputStream 來保存與讀取 Object 對象
//保存對象到文件中
task saveObject(){
Person p=new Person()
p.name="alan"
p.age=18
try{
def desFile=new File("./person.txt")
if(!desFile.exists()){
desFile.createNewFile()
}
desFile.withObjectOutputStream{ out ->
out.writeObject(p)
}
return true
}catch(Exception e){
e.printStackTrace()
}
return false
}
//從文件中讀取Object
task readObject(){
println "readObject start"
def obj=null
try{
def file=new File("./person.txt")
if(file==null || !file.exists())
println "file==null"
return null
file.withObjectInputStream{input ->
obj=input.readObject()
if(obj!=null){
println "name=$obj.name"
println "age=$obj.age"
}else{
println "obj==null"
}
}
}catch(Exception e){
e.printStackTrace()
}
println "readObject end"
}
class Person{
private String name
private int age
}
//讀寫的對象須要支持序列化,不然會報java.io.NotSerializableException
複製代碼