国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 學院 > 開發設計 > 正文

2Groovy閉包與方法引用

2019-11-09 17:00:38
字體:
來源:轉載
供稿:網友

Groovy閉包與方法引用

本文主要介紹閉包,方法引用相關知識。 閉包是{ [closureParameters -> ] statements }這種形式的代碼塊,可以接收參數,返回值,并且可以復制給某個變量,閉包里面可以引用外部的變量。具體可參考http://docs.groovy-lang.org/next/html/documentation/#_closures ,里面說的很詳細。 閉包肯定會返回值,不像方法可能無返回值。

this、owner和delegate

每個閉包都有這3個概念,this、owner和delegate,這3個概念很像,容易搞糊涂。

this:定義閉包的class對象owner:定義閉包的class對象或者閉包對象delegate:一個第三方對象,如果閉包內找不到方法或者屬性就去delegate里面找。

this

一個閉包的this指向的必然是一個class對象,而不是閉包對象,如下所示,

Enclosing內的閉包whatIsThis的this指向Enclosing對象。 而EnclosedInInnerClass里面,閉包cl定義在Inner里面,所以cl的this指針是Inner對象而不是EnclosedInInnerClass對象。NestedClosures里面的閉包cl是定義在另一個閉包nestedClosures里面的,所以cl的this是NestedClosures對象,而不是nestedClosures閉包class Enclosing { void run() { def whatIsThisObject = { getThisObject() } assert whatIsThisObject() == this def whatIsThis = { this } assert whatIsThis() == this }}class EnclosedInInnerClass { class Inner { Closure cl = { this } } void run() { def inner = new Inner() assert inner.cl() == inner }}class NestedClosures { void run() { def nestedClosures = { def cl = { this } cl() } assert nestedClosures() == this }}

owner

owner跟this基本一樣,唯一不同就是owner可以是閉包。所以下邊代碼里的cl的owner就是nestedClosures。

class NestedClosures { void run() { def nestedClosures = { def cl = { owner } cl() } assert nestedClosures() == nestedClosures }}

delegate

delegate是groovy里比較難理解的概念,簡單的說如果一個閉包在執行的時候發現某個參數未定義,那么就會去他的owner以及delegate里面找(默認是先owner后delegate)。其實這么說起來delegate就是相當于java里的非靜態內部類持有外部類的引用,delegate就是外部類的引用。默認情況下delegate就是owner。delegate在DSL里面是非常有用的。

例子1

如下所示,say這個閉包需要m變量,但是m未定義,如果直接執行say()肯定不行,在這里我們給say.delegate=eee,而eee這個map里邊是有m這個變量的,所以在L9執行的時候,發現閉包內m未定義,就去他的delegate eee里找,找到了m,所以最后結果就是打印出2

def say = { PRintln m}//say.delegate = [m:2]eee=[m:2]assert eee.m==2say.delegate=eeesay()

例子2

class Person { String name}class Thing { String name}def p = new Person(name: 'Norman')def t = new Thing(name: 'Teapot')//閉包def upperCasedName = { delegate.name.toUpperCase() }upperCasedName.delegate = passert upperCasedName() == 'NORMAN'upperCasedName.delegate = tassert upperCasedName() == 'TEAPOT'

在這里,我們定義了一個閉包upperCasedName,通過指定delegate,改變閉包的執行主體,這看起來和傳函數參數類似。閉包的delegate是可以不寫的,因為閉包找不到成員的時候就會調用delegate的方法,所以閉包可以這么寫

def upperCasedName = { name.toUpperCase() }

字符串插值

我們知道在字符串插值的時候,可以用${}占位,里面放任意表達式。實際上還可以用${->}占位里面放閉包表達式。此時有一個特性,惰性求值(lazy evaluation).如下所示,對于普通的插值表達式eagerGString,被賦值為1之后,將不再改變。而對于閉包插值lazyGString來說,他每次GString轉換為String的時候都會調用閉包,生成一個新的字符串

def number = 1 def eagerGString = "value == ${number}"def lazyGString = "value == ${ -> number }"assert eagerGString == "value == 1" assert lazyGString == "value == 1" number = 2 assert eagerGString == "value == 1" assert lazyGString == "value == 2"

其他

如果一個函數與一個閉包擁有相同的名稱和參數,則調用的時候將執行函數,而不是閉包

方法引用操作符.&

groovy支持方法引用,如下所示,upper就是一個方法引用,方法引用操作符的左邊是個對象(還可以是this),右邊是方法名。

對象.&方法名

注意下邊fun是一個閉包,fun()是字符串‘EXAMPLE OF METHOD REFERENCE’

def str = 'example of method reference'def str2="s"def fun = str.&toUpperCasedef upper = fun()assert upper == str.toUpperCase()assert upper != str2.toUpperCase()println(upper)println(fun)println(fun())assert fun instanceof Closureassert fun() instanceof String

this.&方法名-方法無參數

方法無參數的時候,閉包就相當于一個簡單的函數指針。

def f(){ println "Hello,world!";}def s=this.&f;s();

this.&方法名-方法有參數

這個就更吊了,只要有方法名,可以訪問不同類型的對象,如下所示,reference是個閉包,往里面傳個’foo’就會調用doSomething(String str)方法,往里頭傳個123,就會調用doSomething(Integer x)方法,這個簡直是多態的升級版。

def doSomething(String str) { str.toUpperCase() } def doSomething(Integer x) { 2*x } def reference = this.&doSomething assert reference('foo') == 'FOO' assert reference(123) == 246

單參數閉包隱藏參數

如下所示filter是個閉包,他有且只有一個參數,這個參數就可以隱藏,用到的時候用it來指代(用法有點像this)

def filter = { it.contains 'G' }assert filter("Groovy")==true

SAM(single abstract method)

A SAM type is a type which defines a single abstract method. This includes:

interface Predicate<T> { boolean accept(T obj)}

Thanks to

http://docs.groovy-lang.org/next/html/documentation/#_closures groovy 官方sdk http://groovy.zeroleaf.com/ http://wiki.jikexueyuan.com/project/deep-android-gradle/four-two.html http://dublintech.blogspot.hk/2014/05/groovy-closures-this-owner-delegate.html


發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 长汀县| 开远市| 偏关县| 加查县| 古交市| 电白县| 金乡县| 昌图县| 福鼎市| 平阴县| 汕头市| 涡阳县| 政和县| 大洼县| 正安县| 曲靖市| 临泉县| 雷山县| 昔阳县| 阆中市| 新绛县| 紫阳县| 玉门市| 井冈山市| 定远县| 正蓝旗| 中江县| 丹凤县| 镶黄旗| 彰化市| 个旧市| 霍邱县| 金湖县| 沂源县| 汝南县| 峨边| 广灵县| 朔州市| 阳新县| 乌兰浩特市| 宿迁市|