2010-03-02 65 views
19

關閉內部代碼可以參考it變量。Groovy使用'it'嵌套關閉

8.times { println it } 

def mywith(Closure closure) { 
    closure() 
} 

mywith { println it } 

這種行爲記住,你不能指望下面的代碼打印0011

2.times { 
    println it 

    mywith { 
     println it 
    } 
} 

,而是我必須寫

2.times { i -> 
    println i 

    mywith { 
     println i 
    } 
} 

我的問題是:爲什麼沒有參數的關閉覆蓋it變量,即使他們不需要它。

回答

13

我覺得它有什麼做用Groovy的formal Closure definition

罩可以有1個... N參數, 可以靜態類型或 類型化。第一個參數是 ,如果沒有明確指定 參數,則可通過隱式非類型化 參數命名該參數。如果主叫方 未指定任何參數,則第一個參數(以及其擴展 it)將爲空。

這意味着,一個Groovy封閉總會有至少一個說法,叫(如果不是另有規定),如果不是作爲一個參數給出將是無效的。

第二個示例使用封閉閉包的作用域。

+0

感謝您的正式定義 – 2010-03-02 10:17:03

19

如果你像這樣定義

def closure = {println "i am a closure"} 

它似乎沒有參數關閉,但實際上它有一個名爲it一個隱含參數。這是通過證實:

def closure = {println "i am a closure with arg $it"} 
closure("foo") 

它打印

「我與ARG FOO封閉」

如果你真的要定義一個閉包取0參數,使用這個:

def closure = {-> println "i am a closure"} 

因此,您的示例可以改寫爲:

2.times { 
    println it 

    mywith {-> 
     println it 
    } 
} 
+0

謝謝。 mini-dsls中顯式的零參數閉包不會很好看。 – 2010-03-03 07:02:33

+0

所以我相信在這種情況下,在mywith嵌套閉包中打印的'it'變量是[自由變量](http://groovy.codehaus.org/Closures#Closures-Freevariables)。 – TheAmpersand 2013-11-06 14:09:44