2015-10-09 43 views
2

Groovy的版本:2.4.3 JVM:1.8.0_60供應商:Oracle公司操作系統:Mac OS X發起授權領域成爲一個封閉空,Groovy的

import groovy.transform.* 

@Canonical 
class A { 
    def f() { 
     map = [:] //map is not null 
     3.times { 
      assert map != null // failed, map is null?! 
     } 
    } 

    @Delegate 
    Map map 
} 
new A().f() 

當我打電話F(),我得到了一個斷言失敗,這意味着映射爲空。但是,如果我刪除註釋'@Delegate',那麼不會有任何問題。或者,如果斷言不在閉包中,也沒有問題。我的問題是爲什麼委託字段在關閉中或不在關閉中表現不同?如果這是因爲閉包中的映射與A類中的對象不是同一個對象,爲什麼它在刪除註釋後工作?

import groovy.transform.* 

@Canonical 
class A { 
    def f() { 
     map = [:] 
     3.times { 
      assert map != null // No problem, map is not null 
     } 
    } 

    Map map 
} 
new A().f() 

或者

import groovy.transform.* 

@Canonical 
class A { 
    def f() { 
     map = [:] 
     assert map != null //no problem too 
    } 

    @Delegate 
    Map map 
} 
new A().f() 

回答

2

當你有@Delegate註解,你的類本質上成爲java.util.Map的實現,委託其調用它的領域map。在您的斷言封閉內對map的引用被視爲this.getAt('map')調用,而不是對map字段的引用。由於沒有將值映射到鍵map,所以斷言失敗。

也許這使得它更清晰一點:

import groovy.transform.* 

@Canonical 
class A { 
    def f() { 
     map = [map:'not null'] // delegated map has key 'map' 
     3.times { 
      assert map == 'not null' 
     } 
    } 

    @Delegate 
    Map map 
} 
new A().f() 

的古怪主要有,其中包括使用的事實斷言封閉,其中有resolve strategy是決定引用是如何解決內完成,這樣做的元類。取消關閉和註釋不再有所作爲。

import groovy.transform.* 

@Canonical 
class A { 
    def f() { 
     assert map != null 
    } 

    @Delegate 
    Map map = [:] 
} 
new A().f()