参考和价值比较

时间:2017-12-27 09:31:30

标签: kotlin

实际上,我是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")
}

到目前为止我遇到的所有类的实例如果内容相同则具有相同的引用。我们如何定义两个具有相同内容但引用不同的对象?

3 个答案:

答案 0 :(得分:3)

Reference equality

  

===操作(及其否定对应!==)检查引用相等性。当且仅当a和b指向同一个对象时,a === b才会计算为真。

换句话说,===运算符会比较ab是否相同。在某些基本类型上进行测试可能会导致错失:

一个例子是:

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都是正确的。

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

Structural equality

  

结构相等性由==操作(及其否定对应!=)检查。按照惯例,像a == b这样的表达式被翻译为:

     

a?.equals(b) ?: (b === null)

正如我们上面所看到的,对于像StringInt这样的内置类来说,即使它们的内容相等,也会为引用相等===返回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类没有该表单的构造函数。奇怪。