参考与价值比较

其实我是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指向同一个对象时才计算为真。

换句话说, ===运算符比较ab是否是相同的引用。 在一些基本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==bc==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)

正如我们上面看到的那样,对于像StringInt这样的内置类来说,对于引用相等===即使它们的内容相等,也是完全正常的。 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)