由于是學(xué)習(xí)Groovy基礎(chǔ)語法帘睦,開始我選擇的IDE是Intellij IDEA,大家可以選擇其它IDE族吻,但是都需要配置Groovy環(huán)境變量和Java環(huán)境變量暴心,這里就不一一贅述了。
Groovy中變量
Groovy沒有基本類型浩嫌,對于一些像int類型都會被包裝成對象類型Integer
int x = 1
println(x.class)
def y = 3.14
println(y.class)
y = 'hello groovy'
println(y.class)
打印輸出如下:
class java.lang.Integer
class java.math.BigDecimal
class java.lang.String
如果一個變量只在本類使用檐迟,可以直接用def去定義該變量;如果該變量還被其他類使用码耐,那么最好還是直接用具體的類型定義該變量追迟,而不是用def去定義。
Groovy中字符串
def name = 'name one'
def doubleName = "name double"
def tripleName = '''name triple'''
println name.class
println doubleName.class
println tripleName.class
打印輸出如下:
class java.lang.String
也就是說骚腥,在一般的情況下敦间,這三者都是可以表示字符串的,但是也有部分區(qū)別束铭,比如:
def sayHello = "Hello: ${name}" //可擴展做任意的表達(dá)式
println sayHello.class
println sayHello
打印輸出如下:
class org.codehaus.groovy.runtime.GStringImpl
Hello: name one
只有雙引號才可以做這種擴展廓块,注意這里的類型是GStringImpl,也就是GString的實現(xiàn)類契沫。
對于三引號带猴,也有其他兩者做不到的,比如懈万,按照某個規(guī)則顯示:
def tripleName = '''\
line one
line two
line three\
'''
打印輸出如下:
line one
line two
line three
對于一些字符串方法拴清,字符串填充center、padLeft钞速;比較大小str > str2贷掖;reverse()、capitalize()渴语、isNumber()苹威,這些方法在這里就不做贅述了,大家可以自行嘗試驾凶。
邏輯控制
由于這里if/else和while循環(huán)和Java程序使用相似牙甫,故這里只選switch/case和for循環(huán)來講掷酗。
- switch/case
def n = 1.23
def result
switch (n) {
case 'hello':
result = 'find hello'
break
case 'groovy':
result = 'find groovy'
break
case [1, 2, 3, 'hello groovy']: //列表
result = 'find list'
break
case 12..30:
result = 'find range' //范圍
break
case Integer:
result = 'find integer'
break
case BigDecimal:
result = 'find bigDecimal'
break
default:
result = 'find default'
break
}
println result
打印輸出如下:
find bigDecimal
for循環(huán)
def sum = 0
for (i in 0..9) {
sum += i
}
sum = 0
//對List的循環(huán)
for (i in [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]) {
sum += i
}
sum = 0
//對Map進行循環(huán)
for (i in ['合肥':1, '杭州':2, '南京':3]) {
sum += i.value
}
println sum
閉包
閉包是Groovy的一個非常重要的特性,可以說它是DSL的基礎(chǔ)窟哺。閉包不是Groovy的首創(chuàng)泻轰,但是它支持這一重要特性,這就使代碼靈活且轨、輕量浮声、可復(fù)用,再也不用像Java一樣動不動就要用一個類了旋奢。
def clouser = {
println 'Hello groovy!'
}
這種寫法就是閉包泳挥,我們可以怎樣調(diào)用閉包呢?
clouser.call()
clouser()
上面這兩種寫法都可以調(diào)用閉包至朗。閉包內(nèi)還可以傳入?yún)?shù):
def clouser = {String language ->
println "Hello $language"
}
閉包內(nèi)默認(rèn)有一個it值屉符,用于默認(rèn)參數(shù):
def clouser = {
println "Hello ${it}"
}
clouser.call('groovy!')
clouser('groovy!')
閉包一定是有返回值的,而且默認(rèn)是花括號中的最后一行:
def clouser = {String language ->
"Hello ${language}"
}
def word = clouser('groovy!')
println word
打印輸出如下:
Hello groovy!
接下來我們來驗證返回值是否就是花括號的最后一行:
def clouser = {String language ->
"Hello ${language}"
'Hello Java!'
}
def word = clouser('groovy!')
println word
打印輸出如下:
Hello Java!
輸出結(jié)果也就驗證了花括號的最后一行就是返回值锹引。
閉包的使用
求累積:
int fun(int number) {
def result = 1
1.upto(number, {num -> result *= num})
return result
}
println fun(5)
還可以這樣寫:
int fun(int number) {
def result = 1
1.upto(number) {
num -> result *= num
}
return result
}
求累加:
int fun2(int number) {
def result = 1
number.times {
num -> result += num
}
return result
}
println fun2(5)
要注意矗钟,這里只是累加到4,也就是1+0+1+2+3+4 = 11
字符串與閉包結(jié)合使用
1.字符串的each函數(shù):
def str = 'the 2 add 3 is 5'
str.each {
temp -> print temp
}
打印輸出如下:
the 2 add 3 is 5
2.字符串的find函數(shù):
def finder = str.find {
it.isNumber()
}
println finder
打印輸出如下:
2
也就是說find函數(shù)式查找字符串中符合閉包條件的第一個元素嫌变,找到了就直接返回吨艇。
3.字符串的findAll函數(shù):
println str.findAll {
it.isNumber()
}
打印輸出如下:
[2, 3, 5]
4.字符串的any函數(shù):
println str.any {
it.isNumber()
}
打印輸出如下:
true
只要有一個元素符合閉包的條件,就返回true
5.字符串的every函數(shù):
println str.every {
it.isNumber()
}
打印輸出如下:
false
當(dāng)所有的元素都符合閉包條件的時候初澎,才返回true
6.字符串的collect函數(shù):
println str.collect {
it.toUpperCase()
}
打印輸出如下:
[T, H, E, , 2, , A, D, D, , 3, , I, S, , 5]
閉包進階
閉包的三個重要變量:this秸应、owner、delegate
def scriptClouser = {
println "scriptClouser this:" + this //代表閉包定義處的類
println "scriptClouser owner:" + owner //代表閉包定義處的類或者對象
println "scriptClouser delegate:" + delegate //代表任意對象碑宴,默認(rèn)與owner一致
}
scriptClouser.call()
打印輸出如下:
scriptClouser this:VariableStudy@3efa6afc
scriptClouser owner:VariableStudy@3efa6afc
scriptClouser delegate:VariableStudy@3efa6afc
this、owner桑谍、delegate三者代表同一個對象VariableStudy實例對象
接下來延柠,我們初始化一個內(nèi)部類Person:
class Person {
def classClouser = {
println "classClouser this:" + this
println "classClouser owner:" + owner
println "classClouser delegate:" + delegate
}
def say() {
def classClouser = {
println "methodClouser this:" + this
println "methodClouser owner:" + owner
println "methodClouser delegate:" + delegate
}
classClouser.call()
}
}
Person p = new Person()
p.classClouser.call()
p.say()
打印輸出如下:
classClouser this:Person@6ccead66
classClouser owner:Person@6ccead66
classClouser delegate:Person@6ccead66
methodClouser this:Person@6ccead66
methodClouser owner:Person@6ccead66
methodClouser delegate:Person@6ccead66
this、owner锣披、delegate三者還是表示同一個對象Person實例對象
現(xiàn)在我們在閉包中再定義一個閉包:
def nestClouser = {
def innerClouser = {
println "innerClouser this:" + this
println "innerClouser owner:" + owner
println "innerClouser delegate:" + delegate
}
innerClouser.call()
}
nestClouser.call()
打印輸出如下:
innerClouser this:VariableStudy@a072d8c
innerClouser owner:VariableStudy$_run_closure9@44d88759
innerClouser delegate:VariableStudy$_run_closure9@44d88759
這時候this表示的是類VariableStudy的實例對象贞间,而owner和delegate都表示內(nèi)部閉包中的實例化對象innerClouser。
那么如何修改delegate和owner不一樣呢雹仿?
def nestClouser = {
def innerClouser = {
println "innerClouser this:" + this
println "innerClouser owner:" + owner
println "innerClouser delegate:" + delegate
}
innerClouser.delegate = p //修改默認(rèn)的delegate
innerClouser.call()
}
nestClouser.call()
打印輸出如下:
innerClouser this:VariableStudy@55dee8d0
innerClouser owner:VariableStudy$_run_closure9@239494f6
innerClouser delegate:Person@52765b39
總結(jié):
1.在類或者方法中定義閉包增热,那么this、owner胧辽、delegate都是一樣的(默認(rèn)不改變delegate)峻仇;
2.如果在閉包中又嵌套一個閉包,那么this邑商、owner摄咆、delegate將不再一樣凡蚜,this將指向閉包定義處外層的實例變量或者類本身(最接近的);而owner和delegate都會指向最近的閉包對象吭从;
3.只有人為的修改delegate朝蜘,delegate和owner才會不一樣(this和owner不可以修改)
閉包的委托策略
class Student {
String name
def pretty = {
"my name is ${name}"
}
}
class Teacher {
String name
}
Student stu = new Student(name: "John")
Teacher tea = new Teacher(name: "jack")
println stu.pretty.call()
打印輸出如下:
my name is John
接下來我們做如下的修改:
class Student {
String name
def pretty = {
"my name is ${name}"
}
}
class Teacher {
String name
}
Student stu = new Student(name: "John")
Teacher tea = new Teacher(name: "jack")
stu.pretty.delegate = tea
stu.pretty.resolveStrategy = Closure.DELEGATE_FIRST
println stu.pretty.call()
打印輸出如下:
my name is jack
以上就是閉包的委托策略。
喜歡本篇博客的簡友們涩金,就請來一波點贊谱醇,您的每一次關(guān)注,將成為我前進的動力步做,謝謝副渴!