
关于 Apache Groovy 中的安全导航操作符,你需要了解的
安全导航操作符是任何使用 Groovy 的人的宝贵工具。通过学习这个操作符,你可以编写更健壮、简洁和可读的代码,同时还可以利用 Groovy 语言的独特功能。

在本系列上一篇文章中,你了解了 Groovy 对三元运算符和相关的 Elvis 运算符的实现。Groovy 还有一个绝招,可以进一步简化三元运算符和 Elvis 运算符。它还有助于避免运行时空指针异常:这就是安全导航操作符。(如果你还没有安装 Groovy,请阅读本系列的介绍。)
下面这个脚本,从上一篇文章修改而来,展示了安全导航操作符的工作原理
1 String strParam = "42"
2 int intParam = strParam?.isInteger() ? Integer.parseInt(strParam):0
3 println "strParam = '$strParam' intParam = $intParam"
4 strParam = "xyz"
5 intParam = strParam?.isInteger() ? Integer.parseInt(strParam) : 0
6 println "strParam = '$strParam' intParam = $intParam"
7 strParam = null
8 intParam = strParam?.isInteger() ? Integer.parseInt(strParam) : 0
9 println "strParam = '$strParam' intParam = $intParam"
查看上面的表达式
strParam?.isInteger()
详细来说,Groovy 首先检查 strParam
是否不是 null
,不是空白,不是零,也不是空。换句话说,Groovy 真值,但前提是它通过了这些测试,并且调用了它的 .isInteger()
方法。回想一下,你首先从更改
strParam != null && strParam.isInteger()
到
strParam && strParam.isInteger()
使用 Groovy 真值,你现在处于
strParam?.isInteger()
这个安全导航操作符 ?.
在DRY 原则上得分很高。但除了更紧凑从而更具可读性之外,它还避免了因在一个地方测试一件事而在另一个地方测试另一件事而引入错误。例如,它可以测试两个相似的变量名。最后,使用安全导航操作符时不可能生成空指针异常,这始终是一件好事。
当你运行它时,你会看到
$ groovy Groovy08a.groovy
strParam = ‘42' intParam = 42
strParam = ‘xyz' intParam = 0
strParam = ‘null' intParam = 0
Groovy 3 还实现了安全索引访问操作符 ?[]
,以便在尝试访问数组、列表和映射的元素时提供相同的保护
1 def l = [0,1,2,3]
2 println "l?[4] ${l?[4]}"
3 def l2 = null
4 println "l2?[4] ${l2?[4]}"
5 def m = ['Monday': 42, 'Tuesday': 33]
6 println "m?['Wednesday'] ${m?['Wednesday']}"
7 println "m?.Wednesday ${m?.Wednesday}"
8 def m2 = null
9 println "m2?['Wednesday'] ${m2?['Wednesday']}"
10 println "m2?.Wednesday ${m2?.Wednesday}"
在这里,安全索引和安全导航操作符正在防止尝试使用尚未初始化的列表或映射
$ groovy Groovy08b.groovy
l?[4] null
l2?[4] null
m?[‘Wednesday'] null
m?.Wednesday null
m2?[‘Wednesday'] null
m2?.Wednesday null
结论
Groovy 真值、三元运算符、Elvis 运算符、安全导航和索引操作符,当结合在一起时,将 Groovy 语法和语义提升到一个全新的水平。笨拙的 Java 表达式通过消除相同变量名的重复使用而缩短,并完全可以作为 if
– then
– else
的替代品。这促进了更具功能性的表达方式——例如,返回方法或闭包的值。增加的 DRY 性消除了在正确的位置使用错误变量名的机会。可读性,以及由此带来的可维护性,都得到了提高。
简而言之,这些是使 Groovy 更加 groovy 的另外三个重要贡献。
照片由 Jimmy Nilsson Masth 在 Unsplash 上拍摄