Kotlin에서는 키워드 operator를 통해 연산자 오버로딩이 지원됩니다. 이를 통해 사용자 정의 타입에 대해 표준 연산자(+, -, *, [], == 등)의 자체 로직을 정의할 수 있습니다:
operator 수정자로 마크해야 합니다.예시:
data class Vec2(val x: Int, val y: Int) { operator fun plus(other: Vec2) = Vec2(x + other.x, y + other.y) } val a = Vec2(1,2) val b = Vec2(2,3) val c = a + b // operator fun plus 호출
주의사항 및 최선의 실천 방법:
==와 equals는 일치해야 함).연산자
==의 오버로딩과 메서드equals()의 재정의는 어떻게 다릅니까?
답변: Kotlin에서 연산자 ==는 항상 equals() 메서드를 호출합니다 (사전에 null 체크가 있습니다). operator fun equals(other: Any?): Boolean을 정의하면 항상 이 메서드를 사용하게 됩니다. ==와 equals()가 서로 다르게 작동하게 만들 수는 없습니다.
data class Point(val x: Int, val y: Int) { override operator fun equals(other: Any?): Boolean { ... } } val a = Point(1,2) val b = Point(1,2) println(a == b) // a.equals(b) 호출
역사
명시적인 의미 없이 compareTo 연산자를 오버로딩:
Point 클래스에서 정렬을 사용할 수 있도록 operator fun compareTo를 정의했습니다. 그러나 "더 큼"과 "더 작음"은 명확한 의미가 없었고, 팀의 다양한 멤버가 각기 다른 로직을 작성했습니다. 결과적으로 선택 정렬 과정에서 혼란스러운 버그가 발생했습니다.
역사
양쪽 타입에 대한 연산자의 대칭성을 잊음:
개발자가 operator fun plus(a: Matrix, b: Vector): Matrix를 구현했지만, Vector + Matrix에 대한 작업을 제공하지 않았습니다, 대칭 함수가 구현되지 않았기 때문입니다. 결과적으로 표현식 vector + matrix는 컴파일되지 않았고, 오직 matrix + vector만 작동했습니다. 이로 인해 코드의 여러 부분에서 버그가 발생했습니다.
역사
잘못된 get 연산자 오버로딩:
개발자가 사용자 정의 클래스를 만들면서 operator fun get(index: Int): Foo를 오버로딩했습니다. 경계 체크를 추가하지 않아 존재하지 않는 요소에 접근할 경우 유효하지 않은 필드를 가진 객체를 반환하게 되어 예외를 던지지 않았습니다 — 이로 인해 비즈니스 로직에 "보이지 않는" 오류가 발생했습니다.