(Note:我看过类似的问题(例如this,其中的问题是无法修剪shell命令的输出),但我认为这种情况是不同的。)
我在Groovy中有一个使用参数的管道脚本(通过properties([parameters([...
),当我将参数值插入到双引号字符串中时,它无法对捕获的(我指的是“captured and .trim()d!”)stdout(这是我的用例)甚至简单的字符串文字进行.equals()
检查。
我可以使用.trim()
来解决这个问题,(尽管您可以通过我的回显和检查.length()
来看到,.trim()
没有任何内容),但我怀疑这只是“工作”,因为它执行了一个隐式的.toString()
--这也是一个成功的解决方案。
对我来说,这看起来像是一个bug,但这实际上是我使用Groovy的第一周,所以也许我遗漏了一些东西--有人能解释一下是什么吗?
即使是一个简单的文字"foo"
也会失败(例如"foo".equals("${params.foo_the_parameter}"
)。插入的参数是其他类型的对象还是什么?
[EDIT从@Matias Bjarland得到答案后,我修改了下面的代码,使用println代替shell echo,因为这样输出更简洁。他建议的解决方案反映在注解块中。]
我的时髦代码:
node() {
properties([
parameters([
string(
defaultValue: 'foo',
description: 'This is foo',
name: 'foo_the_parameter'
)
])
])
/* this is what I learned from the accepted answer
bob="${params.foo_the_parameter}"
println("class of interpolated param is ${bob.class}")
simple_foo="foo"
println("class of \"foo\" is ${simple_foo.class}")
*/
echoed_foo = sh(script:"echo 'foo'", returnStdout: true).trim()
println "echoed foo is [$echoed_foo], params foo is [${params.foo_the_parameter}]";
echo_foo_length = echoed_foo.length()
dqs_foo_length = "${params.foo_the_parameter}".length()
println "their lengths are: echo: [$echo_foo_length] and dqs: [$dqs_foo_length]";
if (echoed_foo.equals("${params.foo_the_parameter}")) {
println "SUCCESS they are equals()"
}
else {
println "FAIL they are not equals()" //this one fires
}
if (echoed_foo.equals("${params.foo_the_parameter}".trim())) {
println "SUCCESS they are equals() after the dqs gets a trim()" //this one fires
}
else {
println "FAIL they are not equals()after the dqs gets a trim()"
}
if (echoed_foo.equals("${params.foo_the_parameter}".toString())) {
println "SUCCESS they are equals() after the dqs gets a toString()" //this one fires
}
else {
println "FAIL they are not equals()after the dqs gets a toString()"
}
if ("foo".equals("${params.foo_the_parameter}")) {
println "SUCCESS at least a simple literal \"foo\" works"
}
else {
println "FAIL even a simple literal \"foo\" fails to be .equals() with the interpolated parameter" //this one fires
}
}
Jenkins输出:
Started by user Michael South
[Office365connector] No webhooks to notify
Obtained jenkins.groovy from git git@github.redacted.com:msouth/test_groovy_equals.git
Running in Durability level: MAX_SURVIVABILITY
[Pipeline] node
Running on subnet_mon_02 in /opt/jenkins/m1/workspace/field-analytics-org/test_string_equals
[Pipeline] {
[Pipeline] properties
[Pipeline] sh
[test_string_equals] Running shell script
+ echo foo
[Pipeline] echo
echoed foo is [foo], params foo is [foo]
[Pipeline] echo
their lengths are: echo: [3] and dqs: [3]
[Pipeline] echo
FAIL they are not equals()
[Pipeline] echo
SUCCESS they are equals() after the dqs gets a trim()
[Pipeline] echo
SUCCESS they are equals() after the dqs gets a toString()
[Pipeline] echo
FAIL even a simple literal "foo" fails to be .equals() with the interpolated parameter
[Pipeline] }
[Pipeline] // node
[Pipeline] End of Pipeline
[Office365connector] No webhooks to notify
Finished: SUCCESS
2条答案
按热度按时间hmtdttj41#
在Groovy中,您只需使用
==
来比较字符串在Java中,我们使用
String.equals()
是因为str1 == str2
并不像我们所期望的那样:Java比较的是引用而不是值。在Groovy中,您只需编写
str1 == str2
,它就会执行您希望它执行的操作。Groovy使用String.compareTo()
比较值,当结果为0
时返回true
。fd3cxomn2#
不确定这是否是您要访问的内容,但请考虑下面的groovy代码:
运行时将打印:
换句话说,字符串插值将导致groovy GString的示例,它不一定等于具有相同内容的字符串。使用
.toString()
强制求值解决了这个特定问题。引用groovy关于字符串插值的文档:
任何Groovy表达式都可以插入到所有字符串文字中,除了单引号和三重单引号字符串。插值是在计算字符串时将字符串中的占位符替换为其值的操作。占位符表达式由${}括起,对于带点的表达式,则以$为前缀。当GString被传递给一个方法时,占位符内的表达式值被计算为它的字符串表示形式,该方法通过在该表达式上调用toString()将String作为参数。
换句话说,您必须使用以下语句的某种变体将GString示例分配给一个java String计划:
,调用一个接受String的方法(将GString强制转换为字符串),或者调用
gstr.toString()
强制转换。希望能有所帮助。