[英]Why does printing the owner of a closure in a string cause infinite recursion?
我正在玩閉包,看到這種奇怪的行為,我無法解釋:
groovy:000> ({ println owner })()
groovysh_evaluate@200b6145
===> null
groovy:000> ({ println "${owner}" })()
groovysh_evaluate@2bf75a70
===> null
groovy:000> ({ ({ println owner })() })()
groovysh_evaluate$_run_closure1@10f67a01
===> null
groovy:000> ({ ({ println "${owner}" })() })()
ERROR java.lang.StackOverflowError:
null
at groovysh_evaluate$_run_closure1_closure2.doCall (groovysh_evaluate:2)
at groovysh_evaluate$_run_closure1_closure2.doCall (groovysh_evaluate)
at groovysh_evaluate$_run_closure1.doCall (groovysh_evaluate:2)
at groovysh_evaluate$_run_closure1_closure2.doCall (groovysh_evaluate:2)
at groovysh_evaluate$_run_closure1_closure2.doCall (groovysh_evaluate)
at groovysh_evaluate$_run_closure1.doCall (groovysh_evaluate:2)
<stacktrace repeats>
我認為它與${}
本身就是一個閉包這一事實有關,但我無法確定為什么會發生這種情況。 該問題確實與訪問owner
有關,因為我沒有看到它與其他變量/表達式一起發生。 有任何想法嗎?
如果閉包嵌入在GString中,則不會在閉包上調用toString()
,而不像GString中嵌入的變量。 在上面你看到錯誤的情況下, owner
是周圍的閉包,並且不會在閉包上調用toString()
。
要解決它,必須在owner
顯式調用toString()
,如:
({ ({ println "${owner.toString()}" })() })()
這同樣適用於我們構建的多個嵌套級別的閉包。
({ ({ ({ println "${owner.toString()}" })() })() })()
通過適當的縮進,它看起來像:
({
({
({
println "${owner.toString()}"
})()
})()
})()
可以用一個簡單的例子來解釋這種行為。
def clos = {return {"hello"}}
println "${clos()}" //prints nothing
println "${clos()()}" //prints hello
錯誤說明: -
現在遇到面臨的錯誤,如前所述,當一個閉包嵌入在GString中時,在閉包上不會調用toString()
。 而是調用閉包,然后在被調用閉包的結果上調用/應用toString()
。 意思是:
"$owner"
等同於owner().toString()
。
在上面的例子中,在調用外部閉包時,它最終通過GString實現[ "$owner"
]調用自身,並且調用增長為遞歸,因此發生堆棧溢出錯誤。
注意:
當您應用GString的變量很簡單時,可以省略{}
。 "${myVariable}"
與"$myVariable"
相同。 只要您訪問變量的簡單屬性,就可以這樣做。 "$myVariable.class.name"
很好(只要myVariable不是地圖)。 但是當涉及方法調用時需要花括號"${myVariable.toString()}"
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.