我今天遇到了一段糟糕的代码,相当于:
[["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 将打开一个 List。
如果您没有定义类型(或将其设置为 List),它将按照您的预期运行:
// Both print '[a]'
[['a']].each { it -> println it }
[['a']].each { List it -> println it }
但是,如果您定义了一个类型,它将尝试解开列表并将内容应用于定义的参数,因此:
// Prints 'a'
[['a']].each { String it -> println it }
把它想象成 java 中的可变参数,或者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" }
第二个输出
只需注意这一点:
println (["asdf"] as String)
可能等同于:
List<String> list = ["asdf"]
println list.toString()