Groovy 基礎之類型與閉包

Groovy

簡介

Groovy是一種DSL語言java

DSL的全稱是Domain Specific Language,即領域特定語言,或者直接翻譯成「特定領域的語言」,其實就是這個語言不通用,只能用於特定的某個領域,俗稱「小語言」。所以DSL也是語言。編程

  • 是一種基於JVM的敏捷性開發語言
  • 結合Python、Ruby與Smalltalk的許多強大特性
  • 能夠與Java完美結合,而且可使用Java中全部的庫

特性

  • 語法上支持動態類型、閉包等新一代語言特性
  • 無縫銜接全部已經集成的Java庫
  • 不只支持面向對象編程,也支持面向過程bianc

優點

  • 一種更加敏捷的編程語言
  • 入門簡單,功能強大
  • 不只能夠做爲編程語言,也能夠做爲腳本語言

變量及定義

Groovy 變量類型分爲基本類型與對象類型,定義分爲強類型定義與弱類型定義 強類型定義:使用一個具體的類型,例如int x = 10 弱類型定義:使用一個def做爲變量的修飾符,例如 def y = 10.9api

//強類型定義的就是一個具體的類型
int x=10
double y = 10
//println x.class
//println(y.class)

//def 定義的是一個弱類型,就是object類型
def x_1 = 10
def u_1 = 23.4
def s = "cxm"
//能夠從新賦值成string字符串類型
x_1 = "yif"
println(x_1.class)
println(u_1.class)
println(s.class)
複製代碼

String 用法

String 中使用了三種不一樣的引號進行定義變量數組

  • 單引號進行定義字符串
  • 兩個單引號及雙引號定義字符串能夠進行擴展輸出內容
  • 三個單引號進行定義字符串能夠格式化輸出
def name = 'this is \'a\' name'
//println name.class
//用三個單引號來進行定義string類型,能夠格式化輸出字符串
def thuplename = '''this is name'''
def linename = '''\
line one
line two
line three
'''
//雙引號定義的字符串能夠擴展
def doublename = "this is name"
def kuoname = "name"
def helloname = "hello $kuoname"
println helloname
//輸出class org.codehaus.groovy.runtime.GStringImpl
println helloname.class
//println doublename
//println linename
//println thuplename.class

def sum = "the sum of 2 and 3 is Equals ${2+3}"//能夠擴展任意的表達式
println sum

def result = echo(sum)
println result
//Groovy 編譯器直接將GStringImpl類型轉換成String 類型輸出
println result.class
String echo(String msg){
    return  msg
}
複製代碼

String 經常使用API

/* ====== 字符串方法 ====== */
//1. 字符串填充
def str = "groovy hello"
//center 進行填充字符串,總共字符串長度爲8 以當前字符串爲中心向兩邊進行填充
println str.center(9, "a")
//將字符串追加到當前字符串左邊
println str.padLeft(8, "a")

//2. 字符串比較
def str2 = "hello"
//使用方法
println str2.compareTo(str)
//使用操做符
println str2 > str

//3. 索引:獲取字符串中的某個索引
//經過方法獲取
println str2.getAt(1)
//經過中括號傳入下標進行獲取
println str2[1]
//傳入一個範圍獲取字符串中的值,先後都包括
println str2[0..1]

//4. 字符串加減操做
//若是一個字符串中包含另外一個字符直接相減 就獲取減去的字符,不包括,則仍是原來字符
println str.minus(str2)

println str.reverse()
//對字符串進行首字母大寫
println str.capitalize()
複製代碼

循環結構使用

  • Switch 使用與Java類型,但在Groovy中又新加了許多新的聲明,能夠進行列表與數組或者類型的輸出
  • for 循環與Java相似
//1. switch 使用
def result = 10
def x = 100
switch (x){
    case 123:
        result = 123
        break
    case '123':
        result = '123'
        break
    case [10.12,1,2,3,"hi"]://列表
        result = 'list'
        break
    case 1..23://數組
        result = 'range'
        break
    case Integer:
        result = "Integer"
        break
    case BigDecimal:
        result = "BigDecimal"
        break
    default:
        result = 'default'
        break
}
println result

//2. 對範圍的for循環
def sum = 0
for(i in 0..9){
    sum += i
}
println sum

//對list的循環
sum = 0
for(i in [12,23,35,45]){
    sum += i
}
println sum

//對map進行循環
sum = 0
for(i in ["lili":3,"yif":23,"cmx":34]){
    sum += i.value
}
println sum
複製代碼

閉包

Groovy中有一種特殊的類型,叫作Closure,翻譯過來就是閉包,這是一種相似於C語言中函數指針的東西。閉包用起來很是方便,在Groovy中,閉包做爲一種特殊的數據類型而存在,閉包能夠做爲方法的參數和返回值,也能夠做爲一個變量而存在。 聲明閉包: 例如:數據結構

def a = {
	//大括號中進行代碼的操做輸出,若是須要變量能夠進行變量聲明
	String name ->
}
複製代碼

調用閉包:閉包

  1. 直接變量加括號進行調用
  2. 經過方法名加call方法進行調用

閉包必定有返回值,但不加return返回值爲null編程語言

def clouser = {println 'hello groovy'}
//調用閉包
clouser.call()
//或者經過變量加括號進行調用
clouser()

//閉包中增長參數
def clouserresult = {String name -> println "hello ${name}"}
clouserresult.call('yif')
def name = 'ztz'
clouserresult('yif')
clouserresult(name)

//傳入多個參數
def clouserresulttwo = {String tip,Integer age -> println "hello ${tip},and age is $age"}
clouserresulttwo('yif',25)

//閉包默認參數it
def test = {println "hello $it"}
test('yyy')

//閉包必定有返回值
//def returnresult = { String a -> return "hello $a"}
//不加return 也有返回值 值爲 null
def returnresult = { String a -> println "hello $a"}
def cosule = returnresult('cxv')
println cosule
複製代碼

閉包用法

  • 與基本類型進行結合使用
  • 與String 類型進行結合使用
  • 與數據結構結合使用
  • 與文件結合使用
基本類型使用

階乘與累加求和函數

// 閉包做爲方法參數的最後一個,能夠直接放到外面
def x = 5
println fgb(x) //實現當前數字的階乘 int fgb(int number){
    int result = 1
    //upto 來實現階乘的乘法,進行循環處理
    1.upto(number,{num -> result *= num})
    return result
}

//downto 來實現階乘
int fab(int number){
    int result = 1
    //閉包放在方法外與裏面效果同樣
    number.downto(1){
        num -> result *= num
    }
    return result
}
println fab(x) //用times 來實現累加,不能用來實現階乘,由於源碼中是從0開始的 int cal(int number){
    int result = 0
    number.times {
        num -> result += num
    }
    return result
}
println cal(5) 複製代碼
字符串與閉包結合使用
/** * 字符串與閉包結合使用 */
def string = "this is 2 to 4 result 6"
string.each {
    //multiply 將每一個字符進行翻倍
    String tmp -> print tmp.multiply(2)
}
println()
//each 返回值就是調用者自己
println string.each {}

//find 查找第一個知足條件的
println string.find{
    String num -> num.isNumber()
}

//findAll 查找因此知足條件的
def list = string.findAll{
    String num -> num.isNumber()
}
println list.toListString()

//any 用來判斷是否知足某個條件
def anyresult = string.any {
    String num -> num.isNumber()
}
println anyresult

//every 用來判斷每一項都知足某個條件
def everyresult = string.every {
    String num -> num.isNumber()
}
println everyresult

def str = string.collect{it.toUpperCase() }
println str.toListString()
複製代碼

閉包三個重要變量

閉包三個重要變量this owner delegate 默認都是最近的類對象this

  • 若是在類中或者方法中定義閉包,那麼這三個變量輸出結果都是同樣的
  • 若是在閉包中嵌套一個閉包,那麼這三個變量結果不同,this還指向類對象,而owner與delegate指向的是最近的閉包對象
  • 若是人爲的修改delegate指向的對象,那麼owner與delegate輸出結果就不同了
  • this與owner 是不能修改的,一旦定義就明確,而delegate是能夠作任意修改的
def script = {
    //這輸出的是類的對象
    println "script this:" + this//表明閉包定義處的類
    println "script owner:"+owner //表明閉包定義處的類和對象
    println "script delegate:"+delegate//表明任意對象,默認與owner一致
}
script()

//定義一個內部類
class Person{
    //這輸出的都是類的字節碼,由於是static
    def static classClourse = {
        println "classClourse this:" + this
        println "classClourse owner:"+owner
        println "classClourse delegate:"+delegate
    }

    def static say(){
        def classClourse = {
            println "method classClourse this:" + this
            println "method classClourse owner:"+owner
            println "method classClourse delegate:"+delegate
        }
        classClourse.call()
    }
}
Person person = new Person()
//person.classClourse.call()
//person.say()
Person.classClourse.call()
Person.say()

//閉包中定義閉包
def nestClourse = {
    def innerClourse = {
        println "innerClourse this:" + this
        println "innerClourse owner:"+owner
        println "innerClourse delegate:"+delegate
    }
    innerClourse.delegate = person// 修改默認的delegate
    innerClourse.call()
}
nestClourse.call()
複製代碼
閉包委託策略

經過委託delegate的方式,來人爲的修改原對象屬性的值 委託策略Closure.DELEGATE_FIRSTspa

  • DELEGATE_FIRST先從委託屬性中尋找,沒有找到再從owner中尋找;
  • DELEGATE_ONLY只從委託中尋找,沒有就報錯
/* 閉包委託策略 */
class Stu{
    String name
    def printName = {" my name is $name"}
    String toString(){
        printName.call()
    }
}

class Tea{
    String name
}

def stu = new Stu(name: "yif")
def tea = new Tea(name: "fxy")
println stu.toString()
stu.printName.delegate = tea
//修改閉包委託策略,DELEGATE_FIRST先從委託屬性中尋找,沒有找到再從owner中尋找;DELEGATE_ONLY只從委託中尋找,沒有就報錯
stu.printName.resolveStrategy = Closure.DELEGATE_FIRST
//若是tea中沒有這個變量name,就會從owner中尋找,找到stu中name,輸出就是stu中的結果
println stu.toString()
複製代碼

歡迎訪問我的博客 Yif博客

相關文章
相關標籤/搜索