問題爲什麼在Groovy閉包中設置的實例變量的值在外面不可見?
爲什麼methodA()
打印set within run
,而不是set within closure
?
代碼示例
class GroovyClosureVariableScopingTest extends Script {
String s
Object run() {
s = "set within run"
println "value of s in run(): $s"
[1].each {
s = "set within closure"
println "value of s in each()-closure: $s"
methodA()
}
}
void methodA() {
println "value of s in methodA(): $s"
}
}
實際輸出
value of s in run(): set within run
value of s in each()-closure: set within closure
value of s in methodA(): set within run // <- Surprised to see the original value
預期輸出
value of s in run(): set in run
value of s in each()-closure: set within closure
value of s in methodA(): set within closure // <- Whould have expected this value
詳細說明
我還不完全瞭解變量作用域在上面的例子中是如何工作的。我預計s
是該類的一個屬性(一個公共實例變量),我認爲我將它保留在each
-closure內的值賦給它。但似乎並非如此。
s
爲什麼不保留從關閉中分配的值?
解決方案/解決方法
傳遞s
作爲參數傳遞給methodA()
作品。看到線條評論// Change
。
class GroovyClosureVariableScopingTest extends Script {
String s
Object run() {
s = "set within run"
println "value of s in run(): $s"
[1].each {
s = "set within closure"
println "value of s in each()-closure: $s"
methodA(s) // Change
}
}
void methodA(s) { // Change
println "value of s in methodA(): $s"
}
}
參考
與此同時,變量仍然可用通常對 封閉的範圍,因此,閉合件可以讀/更改任何這樣的值,和 來自外部作用域的代碼可能會讀取/更改相同的變量。
版本
- Groovy的1.8.6
- Groovy的Eclipse插件2.8.0
- Eclipse平臺3.8.1
這是什麼groovy版本,你如何運行這個類的代碼?與'2.3.6'和一個稍微簡單的版本,我得到了預期的結果。與您的代碼(不擴展'腳本')它也按預期工作) – cfrick 2014-09-11 08:11:10
@cfrick我已經將信息添加到上述問題。 – Lernkurve 2014-09-11 08:18:40
不妨是舊版本的verison或者那裏的一個bug。你用'setS(...)'試過了嗎? – cfrick 2014-09-11 08:41:10