3

今日、これに相当する悪いコードの塊に出くわしました。

[["asdf"]].each {String str -> println str}

println (["asdf"] as String)

これを groovy コンソール ( groovysh) に入れると、次のように表示されます。

asdf

[asdf]

出力に違いがある理由を誰か説明できますか?

4

2 に答える 2

5

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"
}
于 2012-09-14T09:22:41.480 に答える
1

最初の出力

確かなことはわかりませんが、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()
于 2012-09-14T03:48:13.927 に答える