​鸿蒙开发踩坑日记:一个运算符优先级引发的“血案”

186 阅读1分钟

问题是怎么来的?

今天在写鸿蒙应用的时候,遇到了一个让我差点砸键盘的Bug。场景大概是这样的:我需要判断一个图片列表pictureList是否为空,或者长度是不是负数(虽然理论上不可能有负数,但为了防御性编程还是加了判断)。于是随手写下了这段代码:

if (pictureList?.length ?? 0 < 0) {
   // 某些代码
}

结果发现,当pictureList的长度是2的时候,这段if里的代码居然执行了!我当场懵了:2明明大于0啊,这条件怎么会成立呢?当我改成下面这样时,结果又正常了:

if ((pictureList?.length ?? 0) < 0) {
   // 代码不执行了!
}

这到底是为啥??

优先级问题浮出水面

原代码pictureList?.length ?? 0 < 0的实际执行顺序是:先算0 < 0(结果是false),再合并空值。比如当pictureList.length=2时,表达式变成2 ?? false,结果就是2,而if (2)会被转成true

对比正确写法(pictureList?.length ?? 0) < 0,括号强制先合并空值再比较,最终结果为2 < 0 → false

总结:优先级和隐式类型转换是元凶

  • 优先级陷阱:比较符(<)优先级高于空值合并符(??),导致逻辑被拆分

  • 隐式转换规则:ArkTS中,非布尔值在if中会被自动转布尔值(0→false,非0数字→true