Kotlin中使用and做空检查报错,&&却正常的原因是什么?
Kotlin 中
&&/|| 与 and/or 的核心差异 1. 求值策略不同
&&和||采用短路求值:只要第一个条件能确定整个表达式的结果,后续条件就不会再计算。比如false && 任意表达式里,任意表达式根本不会执行。and和or采用全量计算:不管前面条件的结果是什么,所有条件都会被执行计算。
2. 运算符优先级差异
and/or 的优先级比 !=、== 这类比较运算符低,这就是直接替换会报错的原因:编译器会把 str1 != null and str2 != null 错误解析成 str1 != (null and str2) != null,完全偏离你的逻辑,必须给每个条件单独加括号才能保证运算顺序正确。
3. 智能转换支持差异(核心问题根源)
这是你遇到编译错误的关键原因:
&&/||是 Kotlin 的内置逻辑运算符,编译器能识别它们的逻辑语义,会在条件分支中触发智能类型转换。比如用str1 != null && str2 != null判断后,编译器能确定str1和str2在if分支里一定是非空的,所以允许直接调用.length。and/or是Boolean类型的普通扩展函数,编译器无法识别它们作为逻辑判断的语义,因此不会触发智能转换。哪怕用(str1 != null) and (str2 != null)做判断,编译器仍然认为str1和str2是可空类型,所以不允许直接调用.length,必须用?.或!!.处理。
代码对比验证
正常运行的 && 版本:
var str1: String? = "Good Morning" var str2: String? = "How's it going" if (str1 != null && str2 != null) { println(str1.length + str2.length) // 智能转换生效,无编译错误 }
使用 and 需处理可空的版本:
var str1: String? = "Good Morning" var str2: String? = "How's it going" if ((str1 != null) and (str2 != null)) { println(str1!!.length + str2!!.length) // 必须用!!断言非空,否则编译报错 }
内容的提问来源于stack exchange,提问作者Tobias Mayr
相关产品推荐
相关产品推荐

