课程章节介绍
同学们,今天我们来聊一个非常实用的小知识点——空合并运算符。别被名字吓到,它就是两个问号,写出来就是 `??`。这个运算符的作用很简单:如果它左边的值是空,那么就用右边的值来代替;左边有值,就直接用左边的值。
以前我们要做空值判断,代码很啰嗦。比如我们想给一个变量赋一个默认值,可能会写:
`String result = (someVar != null) ? someVar : '默认值';`
或者更传统的 `if` 判断。现在有了 `??`,就可以直接写成:
`String result = someVar ?? '默认值';`
是不是清爽多了?
你可能会觉得它和我们已经学过的安全导航操作符 `?.` 有点像。`?.` 是帮你安全地访问属性或方法,避免在对象为空的时候爆出空指针异常。而 `??` 是帮你给一个可能为空的东西立刻指派一个默认值。它们经常可以搭配使用,比如:
`String displayName = account?.Name ?? '无名账户';`
如果 `account` 是空的,`account?.Name` 会直接返回空,然后 `??` 发现左侧是空,就把 `'无名账户'` 交给你。如果 `account` 有值,但 `Name` 属性就是 `null`,同样也能兜底。这就把两层保护写在一行里了,非常灵活。
使用 `??` 的时候,有几个小特点要留意。
第一,它是左结合的。也就是说,如果出现一连串的 `??`,比如 `a ?? b ?? c`,实际上会先算 `a ?? b`,如果这个结果还不是空,那就用这个结果;如果还是空,再去计算右边的 `c`。其实就相当于 `(a ?? b) ?? c`。
第二,左边的表达式只会计算一次,不用担心性能问题。而且右边的表达式是“惰性”求值的:只有当左边真的是空时,右边才会被计算。这样,如果右边的值涉及到消耗资源的方法调用,也没关系,只有需要的时候才会触发。
第三,一定要保证左右两边的类型是兼容的。你不能前面是一个 `Integer`,后面给一个 `String`,那样会报错。通常我们会对相同类型的变量使用,或者给一个能匹配的默认值,比如 `String` 配 `String`,`Decimal` 配 `Decimal`。
这样一来,原本好几行的空值检查,一行就解决了,代码的可读性和维护性都提上来了。你们在写触发器、控制器或者服务类的时候,遇到需要给变量设置默认值的场景,就大胆地把 `??` 用起来吧。
关键词
Apex
Salesforce
Developer Guide