使用逻辑运算符“and”进行空值检查时抛出错误,而在Kotlin中不抛出“&&”

ecfsfe2w  于 2022-11-16  发布在  Kotlin
关注(0)|答案(1)|浏览(125)

&&and之间的差异以及||or之间的差异:

  • &&||使用短路评估,而
  • andor始终计算每个条件

Kotlin doc for "and"
但除此之外,我在下面的示例中得到了不同的行为:
使用&&时,这个代码片段可以完美地工作:

var str1: String? = "Good Morning"
var str2: String? = "How's it going"

if (str1 != null && str2 != null) {
    println(str1.length + str2.length)
}

当我用and替换&&时,我必须在这两个条件周围添加括号,否则编译器似乎会感到困惑,因为我会得到错误:Operator '!=' cannot be applied to 'String?' and 'BigInteger'
使用and并添加括号:

var str1: String? = "Good Morning"
var str2: String? = "How's it going"

if ((str1 != null) and (str2 != null)) {
    println(str1.length + str2.length)
}

但最后一个片段抛出:

Only safe (?.) or non-null asserted (!!.) calls are allowed on a nullable receiver of type String?

这两个表达式不是应该做完全相同的事情吗?对两个条件求值,并且只在两个String值都是non-null时执行println?这有什么区别?

rdrgkggo

rdrgkggo1#

&&and的另一个不同之处在于,它引入了从String?String的智能转换,允许您通过说出str1.lengthstr2.length而不是使用str1?.lengthstr2?.length来访问length
来自Kotlin语言规范:
智能造型由以下Kotlin构造引入。

  • 条件表达式(if
  • 当表达式(when);
  • 埃尔维斯算符(算符?:);
  • 安全导航操作员(操作员?.);
  • 逻辑合取表达式(运算符&&);
  • 逻辑或表达式(运算符||);
  • 非空Assert表达式(运算符!!);
  • 强制转换表达式(运算符as);
  • 类型检查表达式(运算符is);
  • 简单作业;
  • 特定于平台的案例:不同的平台可以添加其它种类的表达式,

你需要额外的括号,因为and是中缀函数,比&&有更高的优先级,后者不是中缀函数。

相关问题