본문 바로가기
공부/이펙티브코틀린

아이템 12 - 연산자 오버로드를 할 때는 의미에 맞게 사용하라

by 띵커베르 2024. 4. 7.
728x90
  • 연산자 오버로딩은 굉장히 강력한 기능이지만, 위험할 수 있다
  • 의미가 명확하지 않다면, infix 를 활용한 확장 함수를 사용하는 것이 좋다. 일반적인 이항 연산자 형태처럼 사용할 수 있다
  • infix 함수 규칙
    • 매개변수가 반드시 필요하고, 하나의 매개변수만 가져야 합니다.
    • infix 함수는 멤버 함수 또는 확장 함수여야 합니다.
    • infix 함수는 suspend 될 수 없습니다(코루틴과 관련 있는 경우).
// infix 함수 예시 - 1
@Test
fun `p80_1`() {
    println("Hello".appendExclamation()) // "Hello!"
    println("Hello" add "World") // "Hello World"
}

fun String.appendExclamation(): String = "$this!"

infix fun String.add(other: String): String = "$this $other"
// infix 함수 예시 - 2
@Test
fun `p80_2`() {
    val conetents = Person("contents display")
    val live = Person("live display")

    conetents addFriend live
    conetents.displayFriends() // contents display's friends: live display
}

class Person(val name: String) {
    val friends = mutableListOf<Person>()

    infix fun addFriend(friend: Person) {
        friends.add(friend)
    }

    fun displayFriends() {
        println("$name's friends: ${friends.joinToString { it.name }}")
    }
}

 


 

  • 규칙을 무시해도 되는 경우
    • 위에 설명한 연산자 오버로딩 규칙을 무시해도 되는 중요한 경우가 있다
    • 바로 도메인 특화언어(Domain Specific Language, DSL) 을 설계할 때이다.

 


정리:

  • 이름의 의미에 맞게 사용하자
  • 연산자 의미가 명확하지 않는다면 연산자 오버로딩을 사용하지 않는 것이 좋다
  • 꼭 같은 형태로 사용하고 싶다면 infix 확장 함수 또는 톱레벨 함수를 활용하자
    • 톱레벨: 클래스 또는 다른 대상 내부에 있지않고, 가장 외부에 있는 함수를 의미

 

생각:

확장함수를 좋아는 하는데, infix 확장함수로 좀 더 자연어에 가까운 메서드로 만들어볼 생각도 해보았다.

의미가 명확 하다면 괜찮아 보인다.

DSL 코드는 몇번 본적이 있는데 와닿지가 않아서 좀 더 내공이 쌓이면 다시 봐야할까 싶다..

728x90

댓글