【问题标题】:In Groovy, Is there any way to safely index into a Collection similar to the safe navigation operator?在 Groovy 中,有什么方法可以像安全导航运算符一样安全地索引到 Collection 中?
【发布时间】:2018-02-20 22:10:47
【问题描述】:

这将安全地返回 null 而不会引发任何异常

obj?.prop1?.prop2

我怎样才能为集合做到这一点,它不会抛出索引越界异常?

myarray[400]  //how do I make it return null if myarray.size() < 400 

Collections 有这样的操作符吗?

【问题讨论】:

    标签: groovy


    【解决方案1】:

    这是所有集合的默认行为,除了 groovy 中的数组。

    assert [1,2,3,4][5] == null
    def test = new ArrayList()
    assert test[100] == null
    assert [1:"one", 2:"two"][3] == null
    

    如果您有一个数组,请将其转换为一个列表。

    def realArray = new Object[4]
    realArray[100] // throws exception
    (realArray as List)[100] // null
    

    您可以将列表和映射索引与? 运算符一起使用,方法与使用属性相同:

    def myList = [[name: 'foo'], [name: 'bar']]
    assert myList[0]?.name == 'foo'
    assert myList[1]?.name == 'bar'
    assert myList[2]?.name == null
    

    【讨论】:

    • 但要注意会导致异常的负索引,即:def a = [] ; println a[ -1 ] throws a java.lang.ArrayIndexOutOfBoundsException
    • @tim_yates 知道为什么吗?似乎相当不一致。
    • 对于像我这样的任何 groovy noobs 的附录,如果您需要对变量键名进行映射访问,您可以使用此语法来利用 null 安全运算符:mymap = null@987654328 @mymap?."$keyName"
    • 请注意,test[100] 返回 nullBUT test.get(100) 抛出 IndexOutOfBoundsExceptiontest?.get(100) 也一样
    【解决方案2】:

    您可以使用 get() 代替:

    myarray?.get(400)
    

    【讨论】:

    • 如果索引确实超出范围,这将引发 IndexOutOfBoundsException,这实际上比返回 nullmyarray[400] 的当前行为更糟糕。
    • 其实你是对的。但是 myarray?.getAt(400) 如果超出范围将返回 null。
    • 对于什么版本的 Groovy?我已经测试了 2.4.13、2.4.6、2.0.0 和 1.7.8。
    • 这是不正确的。 ? 只有在 myarray 为空时才有帮助。如果myarray 为空,则表达式的计算终止。否则它会继续并尝试访问第 400 个不存在的项目。我们会得到一个例外。
    猜你喜欢
    • 2012-03-13
    • 1970-01-01
    • 1970-01-01
    • 2013-09-16
    • 1970-01-01
    • 1970-01-01
    • 2016-04-08
    • 2016-04-07
    • 1970-01-01
    相关资源
    最近更新 更多