•
Kotlin에서 동등성에는 두 가지 유형이 있다.
구조적 동등성(Structural Equality)
•
구조적 동등성은 두 객체의 내용이나 구조가 동일한지를 검증한다.
•
구조적 동등성은 == 연산자와 그 반대인 != 로 확인된다.
a?.equals(b) ?: (b === null)
Kotlin
복사
•
a == b 는 위처럼 변환된다.
•
a가 null이 아닐 경우 equals(Any?) 함수를 호출하고 a가 null인 경우 b가 null과 참조적으로 같은지 확인한다.
fun main() {
var a = "hello"
var b = "hello"
var c = null
var d = null
var e = d
println(a == b) // true
println(a == c) // false
println(c == e) // true
}
Kotlin
복사
•
null을 명시적으로 비교할 때 a == null 은 자동으로 a === null 로 변환되므로 코드 최적화가 필요없다.
class Point(val x: Int, val y: Int) {
override fun equals(other: Any?): Boolean {
if (this === other) return true
if (other !is Point) return false
// 구조적 동등성을 위해 속성 비교
return this.x == other.x && this.y == other.y
}
}
Kotlin
복사
•
Kotlin에서 equals() 함수는 모든 클래스에 Any 클래스로부터 상속된다.
•
기본적으로 equals() 함수는 참조적 동등성을 구현하므로 equals() 함수를 오버라이드하여 구조적 동등성을 구현할 수 있다.
•
값 클래스와 데이터 클래스는 equals() 함수를 자동으로 오버라이드하여 제공하며 기본적으로 구조적 동등성을 구현한다.
•
데이터 클래스의 경우 부모 클래스에서 equals() 함수가 final로 지정된 경우 동작이 변하지 않는다.
•
equals() 함수를 오버라이드 하려면 equals(other: Any?): Boolean 함수를 오버라이드해야 하며 같은 이름이지만 다른 시그니처를 가진 함수는 동등성 검사에 영향을 미치지 않는다.
•
Comparable<…> 인터페이스에 의해 정의된 비교는 동등성 연산자의 동작에 영향을 주지 않는다.
참조적 동등성(Referential Equality)
•
참조적 동등성은 두 객체의 메모리 주소를 검증하여 같은 인스턴스인지 확인한다.
•
참조적 동등성은 === 연산자와 그 반대인 !== 로 확인한다.
fun main() {
var a = "Hello"
var b = a
var c = "world"
var d = "world"
println(a === b) // true
println(a === c) // false
println(c === d) // true
}
Kotlin
복사
•
Int 처럼 런타임에 원시 타입으로 표현되는 값의 경우 === 검사는 == 검사와 동일하다.
Kotlin/JS 에서는 참조적 동등성이 다르게 구현된다.
부동 소수점 숫자의 동등성
•
정적으로 부동 소수점 숫자로 타입(Float 또는 Double)이 지정된 피연산자
◦
동등성 검사는 IEEE 754 표준에 따른 부동 소수점 산술을 따른다.
•
정적으로 부동 소수점 숫자로 타입(Float 또는 Double)이 지정되지 않은 피연산자
◦
구조적 동등성이 구현된다.
◦
동등성 검사는 IEEE 표준과 다르다.
1.
NaN은 자기 자신과 같다고 평가
2.
NaN은 다른 모든 요소(POSITIVE_INFINITY 등)보다 큼
3.
-0.0 은 0.0 과 같지 않음
배열의 동등성
•
두 배열이 동일한 요소를 같은 순서로 갖는지 비교하려면 contentEquals() 를 사용하라.