Kotlin

[Kotlin] 중위 호출 & 구조 분해 선언

sh1mj1 2024. 1. 3. 16:03

Kotlin in Action 을 공부하고 Effective kotlin 의 내용을 조금 참조하여 정리한 글입니다.

 

이미지 출처    https://commons.wikimedia.org/wiki/File:Kotlin_Icon.svg

infix call(중위 호출)

우리는 맵을 만들 때 `mapOf` 함수를 사용해서 아래처럼 만들어 왔다.

val map = mapOf(1 to "one", 7 to "seven", 53 to "fifty-three")

그런데 여기서 `to` 는 코틀린의 특별한 키워드가 아닌 일반 함수라고 했다.

이 코드는 infix call(중위 호출)이라는 특별한 방식으로 to 라는 일반 메서드를 호출한 것이다.

 

중위 호출 시에는 수신 객체유일한 메서드 인자 사이에 메서드 이름을 넣는다. (`[수신 객체] [메서드 이름] [유일한 메서드 인자]`)

이 중위 호출이 가능한 메서드는 일반 호출로도 사용할 수 있다.

즉, 아래처럼 일반 호출로 만든 맵도 동작이 동일하다.

@Test
fun infixCall() {
    val map = mapOf(1 to "one", 7 to "seven", 53 to "fifty-three")
    val map2 = mapOf(1.to("one"), 7.to("seven"), 53.to("fifty-three"))

    assert(map == map2)
}

중위 호출은 인자가 하나뿐인 일반 메서드나 인자가 하나뿐인 확장 함수에만 사용할 수 있다.

함수의 중위 호출이 가능하게 하려면 `infix` 변경자를 함수 선언 앞에 추가해주면 된다.

 

`to` 라는 함수 선언부를 간단한 버전으로 보자.

inifx fun Any.to(other: Any) = Pair(this, other)

실제로 to 는 Generic 함수이다.

구조 분해 선언(destructuring declaration)

`to` 함수는 `Pair` 의 인스턴스를 리턴한다. 

`Pair` 는 코틀린 표준 라이브러리이며 두 원소로 이뤄진 순서쌍이다.

 

`Pair` 의 contents 로 두 변수를 즉시 초기화할 수 있다.

val (number, name) = 1 to "one"

이런 기능을 구조 분해 선언(destructuring declaration) 이라고 한다.

to 함수를 사용해 Pair 를 만든 후 구조 분해를 통해 Pair 를 풀기

`Pair` 인스턴스 외에 다른 객체에서도 구조 분해를 적용할 수 있다.

루프에서도 구조 분해 선언을 활용할 수 있다.

이전에  `joinToString` 에서 본 `withIndex` 를 구조 분해 선언과 조합하면 컬렉션 원소의 인덱스와 값을 따로 변수에 담을 수 있다.

val list = listOf(3, 6, 9)

for ((index, element) in list.withIndex()) {
    println("$index: $element")
}
결과
0: 3
1: 6
2: 9

나중에 식의 구조 분해와 구조 분해를 사용해서 여러 변수를 초기화하는 법, convention 에 대해 자세히 다루겠다.

 

코틀린을 잘 모르는 사람이 보면 새로운 맵을 만드는 코드가 코틀린이 제공하는 특별한 문법인 것처럼 느껴지겠지만, 실제로는 일반적인 함수를 더 간결한 구문으로 호출하는 것 뿐이다.

우리도 이러한 형태로 사용하는 함수를 쉽게 선언할 수 있다.