实际上,我是kotlin的新手;因此,这个问题可能非常基础。
根据kotlin文档,可以将两个变量与===
和==
运算符进行比较。
第一个('==')检查它们是否具有相同的内容,第二个('+ ==')检查它们是否具有相同的引用。
但是,我找不到任何内置类,其对象具有相同的内容,但具有不同的引用。
var str1 : String = "Hello World"
var str2 : String = "Hello World"
if( str1 == str2 ){ // yes
print("Their contents are same\n")
{
if( str1 === str2 ){ // yes
print("Their references are same\n")
}
到目前为止我遇到的所有类的实例如果内容相同则具有相同的引用。我们如何定义两个具有相同内容但引用不同的对象?
答案 0 :(得分:3)
===
操作(及其否定对应!==
)检查引用相等性。当且仅当a和b指向同一个对象时,a === b
才会计算为真。
换句话说,===
运算符会比较a
和b
是否相同。在某些基本类型上进行测试可能会导致错失:
一个例子是:
val a:Int? = 123
val b:Int? = 123
println(a === b) // => true
val c:Int? = 130
val d:Int? = 130
println(c === d) // => false
显然,在这两种情况下,a==b
和c==d
都是正确的。
Since string interning is also possible at compile time ===
在简单方案中也会返回true
:
val a = "ala"
val b = "ala"
println(a === b) // => true
val c = "!ala".substring(1)
val d = "!ala".substring(1)
println(c === d) // => false
结构相等性由
==
操作(及其否定对应!=
)检查。按照惯例,像a == b
这样的表达式被翻译为:
a?.equals(b) ?: (b === null)
正如我们上面所看到的,对于像String
和Int
这样的内置类来说,即使它们的内容相等,也会为引用相等===
返回false。 Kotlin定义的类很容易被内容与data classes
进行比较,如下所示:
数据类地址(val city:String,val street1:String)
val a = Address("Warsaw", "Jagielońska")
val b = Address("Warsaw", "Jagielońska")
println(a === b) // => false
println(a == b) // => true
答案 1 :(得分:2)
由于您定义String的方式,===无效。如果使用文字创建字符串,它将指向字符串池中的相同字符串。
var str1 = "Hello World"
var str2 = "Hello World"
val str3 = buildString { "Hello World" }
val str4 = buildString { "Hello World" }
var result = str1===str2 // true
println(result)
result = str1 == str2 // true
println(result)
result = str3 === str4 // false
println(result)
result = str3 == str4 // true
println(result)
答案 2 :(得分:2)
比较String
这样的引用将返回true
,因为JVM通过重用第一个String
实例来优化您的示例代码,因为它无论如何都是不可变的。例如,请参阅有关此here的更多讨论。
如果直接调用类的构造函数,那么您将跳过任何优化,并获得不同的实例:
val i1 = Integer(1)
val i2 = Integer(1)
println(i1 == i2) // true
println(i1 === i2) // false
旁注:在Java中,我已经用new String("Hello world")
展示了这个示例,但显然Kotlin String
类没有该表单的构造函数。奇怪。