如何使用 equals() 和 contains() 检查可空类型的数据?我想它们都是字符串的方法,但为什么它们的行为不同呢?
How to use equals() and contains() to check nullable type of data? I suppose they are both string's methods, but why they behave differently?
案例 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
函数定义为可空字符串引用 String?
上的扩展函数,而 contains
方法定义在不可空 CharSequence
.
上
public actual fun String?.equals(other: String?, ignoreCase: Boolean = false): Boolean = ...
public operator fun CharSequence.contains(other: CharSequence, ignoreCase: Boolean = false): Boolean = ...
在这两种情况下,myStr
都是可为空的字符串,因此您不能直接调用 contains
。您可以使用空安全运算符 ?.
来调用 contains
if(myStr?.contains("hello") == true)
println("contains hello")
else
println("not contains hello")
PS:等式检查时,不需要使用equals
方法,直接使用==
运算符
即可
equals
对可空字符串有效,只是因为它是一种非常特殊的情况。有一个equals
专门为String?
写的。
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?
声明的,因此您不能在可空类型上调用它 通常 .
无论如何,比较相等性的惯用方法是使用 a == b
,对于可为 null 的 a
.
,它转换为 a?.equals(b) ?: (b === null)
也没有理由允许 myStr.contains("hello")
编译,因为 contains
是在不可为 null 的 CharSequence
.
上声明的
operator fun CharSequence.contains(
other: CharSequence,
ignoreCase: Boolean = false
): Boolean
您可以这样检查它,使用可空链接:
if (myStr?.contains("hello") == true)
在第一个示例中,myStr.equals
调用 String?.equals
扩展函数,该函数执行以下操作:
if (this === null)
return other === null
在你的例子中,this
是 null
,而 other
不是 null
,所以 other === null
产生 false
。
在第二个示例中,myStr.contains("hello")
试图调用一个名为 contains
的函数,但它不存在,因为您有一个可为空的 String?
,并且没有contains
为该类型定义的函数。有 CharSequence.contains
函数,但它仅为不可空类型定义。
因此,由于该函数不存在,您会收到编译器错误。
一般情况下,您不需要使用 equals
函数,应该更喜欢 ==
运算符:
val myStr:String? = null
if (myStr == "hello")
println("equals hello")
else
println("not equals hello")
对于contains,可以使用?.
运算符先确保左边的对象不为null:
val myStr:String? = null
if (myStr?.contains("hello") == true)
println("contains hello")
else
println("not contains hello")
这里,myStr?.contains("hello")
产生null
,而null == true
是false
,所以结果是false
。
案例 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
函数定义为可空字符串引用 String?
上的扩展函数,而 contains
方法定义在不可空 CharSequence
.
public actual fun String?.equals(other: String?, ignoreCase: Boolean = false): Boolean = ...
public operator fun CharSequence.contains(other: CharSequence, ignoreCase: Boolean = false): Boolean = ...
在这两种情况下,myStr
都是可为空的字符串,因此您不能直接调用 contains
。您可以使用空安全运算符 ?.
来调用 contains
if(myStr?.contains("hello") == true)
println("contains hello")
else
println("not contains hello")
PS:等式检查时,不需要使用equals
方法,直接使用==
运算符
equals
对可空字符串有效,只是因为它是一种非常特殊的情况。有一个equals
专门为String?
写的。
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?
声明的,因此您不能在可空类型上调用它 通常 .
无论如何,比较相等性的惯用方法是使用 a == b
,对于可为 null 的 a
.
a?.equals(b) ?: (b === null)
也没有理由允许 myStr.contains("hello")
编译,因为 contains
是在不可为 null 的 CharSequence
.
operator fun CharSequence.contains(
other: CharSequence,
ignoreCase: Boolean = false
): Boolean
您可以这样检查它,使用可空链接:
if (myStr?.contains("hello") == true)
在第一个示例中,myStr.equals
调用 String?.equals
扩展函数,该函数执行以下操作:
if (this === null)
return other === null
在你的例子中,this
是 null
,而 other
不是 null
,所以 other === null
产生 false
。
在第二个示例中,myStr.contains("hello")
试图调用一个名为 contains
的函数,但它不存在,因为您有一个可为空的 String?
,并且没有contains
为该类型定义的函数。有 CharSequence.contains
函数,但它仅为不可空类型定义。
因此,由于该函数不存在,您会收到编译器错误。
一般情况下,您不需要使用 equals
函数,应该更喜欢 ==
运算符:
val myStr:String? = null
if (myStr == "hello")
println("equals hello")
else
println("not equals hello")
对于contains,可以使用?.
运算符先确保左边的对象不为null:
val myStr:String? = null
if (myStr?.contains("hello") == true)
println("contains hello")
else
println("not contains hello")
这里,myStr?.contains("hello")
产生null
,而null == true
是false
,所以结果是false
。