参考与价值比较
其实我是kotlin的新手, 因此,这个问题可能是非常基本的。
根据kotlin文档,两个variables可以与===
和==
运算符进行比较。 第一个(’==’)检查它们是否有相同的内容,第二个(’+ ==’)检查它们是否具有相同的引用。 但是,我找不到任何内置类,其对象具有相同的内容,但具有不同的引用。
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") }
到目前为止我所遇到的所有课程的实例,如果内容相同的话,都有相同的参考。 我们如何定义两个具有相同内容但具有不同引用的对象?
参考平等
引用相等是通过
===
操作(和它的否定对象!==
)检查的。a === b
当且仅当a和b指向同一个对象时才计算为真。
换句话说, ===
运算符比较a
和b
是否是相同的引用。 在一些基本types上进行测试可能会因为以下原因而失败:
- 串入国际
- 整数缓存
一个例子是:
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
是真实的。
由于字符串interning在编译时也是可能的, ===
在简单场景中也返回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
这样的expression式被转换为:
a?.equals(b) ?: (b === null)
正如我们上面看到的那样,对于像String
和Int
这样的内置类来说,对于引用相等===
即使它们的内容相等,也是完全正常的。 Kotlin定义的类可以很容易地通过内容与data classes
进行比较 ,如下所示:
数据类地址(val城市:字符串,val street1:字符串)
val a = Address("Warsaw", "Jagielońska") val b = Address("Warsaw", "Jagielońska") println(a === b) // => false println(a == b) // => true
比较像这样的String
引用将返回true
,因为JVM通过重用第一个String
实例来优化您的示例代码,因为无论如何它是不可变的。 例如,在这里看到更多关于这个的讨论。
如果直接调用类的构造函数,则会跳过任何优化,并获取不同的实例:
val i1 = Integer(1) val i2 = Integer(1) println(i1 == i2) // true println(i1 === i2) // false
旁注:在Java中,我会用new String("Hello world")
显示这个例子,但显然Kotlin String
类没有这种forms的构造函数。 奇怪。
由于您定义字符串的方式,===不工作。 如果使用文字创建一个字符串,它将指向字符串池中的相同字符串。
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)