今日、これに相当する悪いコードの塊に出くわしました。
[["asdf"]].each {String str -> println str}
println (["asdf"] as String)
これを groovy コンソール ( groovysh
) に入れると、次のように表示されます。
asdf
[asdf]
出力に違いがある理由を誰か説明できますか?
今日、これに相当する悪いコードの塊に出くわしました。
[["asdf"]].each {String str -> println str}
println (["asdf"] as String)
これを groovy コンソール ( groovysh
) に入れると、次のように表示されます。
asdf
[asdf]
出力に違いがある理由を誰か説明できますか?
Groovyは、クロージャーで定義したタイプに適合することを意味する場合、リストをアンラップします。
タイプを定義しない(またはリストとして設定しない)場合、期待どおりに動作します。
// Both print '[a]'
[['a']].each { it -> println it }
[['a']].each { List it -> println it }
ただし、タイプを定義すると、リストがアンラップされ、定義されたパラメーターにコンテンツが適用されます。したがって、次のようになります。
// Prints 'a'
[['a']].each { String it -> println it }
Javaのvarargs、またはclosure( *it )
Groovyのクロージャーの呼び出しのように考えてください
次のようなことができるので、実際には非常に便利です。
// Tokenize the strings into 2 element lists, then call each with these
// elements in separate variables
['a=b', 'b=c']*.tokenize( '=' )
.each { key, value ->
println "$key = $value"
}
最初の出力
確かなことはわかりませんが、Groovy はリストの単一の要素にクロージャーを適用しようとするようです。
これに注意してください:
[["asdf"]].each {String str -> println str }
これと同等です:
Closure c = { String s -> println s }
c(["asdf"])
そして、これらのテストは経験的証拠を示唆しています。
Closure c = { String s -> println s }
println "c test"
try { c(["asdf","def"]) } catch(Exception ex) { println "no" }
try { c(123) } catch(Exception ex) { println "no" }
try { c([]) } catch(Exception ex) { println "no" }
// this works:
try { c(["asdf"]) } catch(Exception ex) { println "no" }
Closure d = { Integer i -> println i }
println "d test"
try { d([22,33]) } catch(Exception ex) { println "no" }
try { d("abc") } catch(Exception ex) { println "no" }
try { d([]) } catch(Exception ex) { println "no" }
// this works:
try { d([22]) } catch(Exception ex) { println "no" }
2番目の出力
これに注意してください:
println (["asdf"] as String)
おそらくこれと同等です:
List<String> list = ["asdf"]
println list.toString()