Groovy真值问题: String.split()产生空数组,但是是 'true' ? 怎么回事?

6 浏览
0 Comments

Groovy真值问题: String.split()产生空数组,但是是 'true' ? 怎么回事?

以下是我在groovysh shell中采取的一系列步骤,以展示问题。按照Java SDK的预期,String.split() => String[]。当我将其作为连续表达式的一部分进行评估时:changedDirs.split('\r\n').collect{ ... },我的collect会执行1次,但it为空。请允许我解释一下:这段代码在Jenkins服务器上运行,众所周知,Jenkins有一种可以称之为groovy方言的运行方式。但是,不管怎样,在本地使用groovysh进行测试时,我确实得到了一个我没有预期的结果:[]来自String.split()的结果会被评估为truthy

所以,有人能解释一下:

  1. 为什么下面的groovy代码会对String.split()产生truthy的结果,而对于基本的空[]不会产生?
  2. Jenkins是否在做一些奇怪的事情?

groovy:000> [] ? 'true' : 'false'
===> false
groovy:000> changedDirs = ''
===> 
groovy:000> changedDirs.split('\r\n')
===> []
groovy:000> changedDirs.split('\r\n') ? true : false
===> true
groovy:000> result = changedDirs.split('\r\n')
===> []
groovy:000> result ? true : false
===> true
groovy:000> result.class
===> class [Ljava.lang.String;
groovy:000> [] as String[] ? true : false
===> false
groovy:000> 

0
0 Comments

Groovy中的Truthy问题:String.split()生成空数组,但为什么是“true”?为什么会出现这个问题以及解决方法?

问题的原因是,在Groovy中,调用asBoolean()方法时,每个非空数组都会被评估为true,无论数组中的元素是什么。这是Groovy中的“Groovy Truth”规则。

具体来说,在这个例子中,changedDirs.split('\r\n')生成一个包含一个元素(空字符串)的String[]数组。因此,result作为布尔值被评估为true

下面是一个例子来说明这个问题:

groovy:000> ([] as String[]).class
===> class [Ljava.lang.String;
groovy:000> ([] as String[]) ? true : false
===> false
groovy:000> x = ([] as String[])
===> []
groovy:000> x.dump()
===> <[Ljava.lang.String;>
groovy:000> y = "".split(",")
===> []
groovy:000> y.class
===> class [Ljava.lang.String;
groovy:000> y.dump()
===> <[Ljava.lang.String;>
groovy:000> y ? true : false
===> true
groovy:000> y.length
===> 1
groovy:000> x.length
===> 0
groovy:000> y[0].dump()
===> <java.lang.String value= hash=0>
groovy:000> 

从上面的例子可以看出,空数组x的长度为0,因此x被评估为false;而空数组y的长度为1,因此y被评估为true

如果我们看一下Java代码的例子,可以看到String.split(pattern)方法在空字符串的情况下生成一个包含单个元素的数组。

final class Test {
    public static void main(String[] args) {
        String[] array = "".split("\r\n");
        System.out.println(array.length); // 输出:1
    }
}

这个问题的解决方法是使用.inspect()方法来更好地展示问题,而不是使用.dump()方法。

这是我做的解决方法:(changedDirs ?: null)?.split('\r\n'),这样就可以得到我想要的结果。

如果你对这个问题感兴趣,这个Stack Overflow的问题可能会有帮助:Why does "split" on an empty string return a non-empty array?

0