如何使用 equals() 和 contains() 来检查可为空的数据类型?我想它们都是字符串的方法,但为什么它们的行为不同?



CASE 1:它可以编译并运行。为什么null调用equals((时没有异常?

var myStr:String? = null
if (myStr.equals("hello"))  
println("equals hello")
else
println("not equals hello")

案例2:它无法编译。我想这与上面的情况类似,但我错了。为什么?

var myStr:String? = null
if (myStr.contains("hello"))
println("contains hello")
else
println("not contains hello")

equals函数被定义为可为null的String引用String?上的扩展函数,而contains方法被定义为不可为nullCharSequence

public actual fun String?.equals(other: String?, ignoreCase: Boolean = false): Boolean = ...

public operator fun CharSequence.contains(other: CharSequence, ignoreCase: Boolean = false): Boolean = ...

在这两种情况下,myStr都是可以为null的String,因此不能直接调用contains。可以使用空安全运算符?.调用contains

if(myStr?.contains("hello") == true)
println("contains hello")
else
println("not contains hello")

PS:在相等性检查的情况下,您不需要使用equals方法,而是可以使用==运算符

equals对可为null的字符串有效,只是因为这是一种非常特殊的情况。有一个专门为String?编写的equals

fun String?.equals(
other: String?, 
ignoreCase: Boolean = false
): Boolean

这在Int?上不起作用,例如:

var i: Int? = null
if (i.equals(1)) // error here
println("equals 1")
else
println("not equals 1")

equals函数是为Any声明的,而不是为Any?声明的,因此通常不能在可为null的类型上调用它

无论如何,比较相等性的惯用方法是使用a == b,它将a?.equals(b) ?: (b === null)转换为可为null的a

也没有理由允许myStr.contains("hello")编译,因为contains是在不可为null的CharSequence上声明的。

operator fun CharSequence.contains(
other: CharSequence, 
ignoreCase: Boolean = false
): Boolean

您可以这样检查它,使用可为null的链接:

if (myStr?.contains("hello") == true)

在第一个示例中,myStr.equals调用String?.equals扩展函数,该函数执行以下操作:

if (this === null)
return other === null

在您的情况下,thisnull,而other不是null,因此other === null产生false


在第二个示例中,myStr.contains("hello")试图调用一个名为contains的函数,但它不存在,因为您有一个可为null的String?,并且没有为该类型定义contains函数。有CharSequence.contains函数,但它只为不可为null的类型定义。

因此,因为该函数不存在,所以会出现编译器错误。


通常,您不需要使用equals函数,应该更喜欢==运算符:

val myStr:String? = null
if (myStr == "hello")
println("equals hello")
else
println("not equals hello")

对于contains,您可以使用?.运算符来确保左侧的对象首先不为空:

val myStr:String? = null
if (myStr?.contains("hello") == true)
println("contains hello")
else
println("not contains hello")

这里,myStr?.contains("hello")产生null,而null == truefalse,所以结果是false

相关内容

  • 没有找到相关文章

最新更新