Notice
Recent Posts
Recent Comments
Link
Tags
more
관리 메뉴

주완 님의 블로그

구조 분해 선언과 component 함수 (kotlin in action) 본문

Android

구조 분해 선언과 component 함수 (kotlin in action)

vvan2 2025. 6. 11. 11:43

구조 분해 선언과 component 함수

디스트럭쳐링(Destructuring) 이란?

  • 한 객체가 가진 여러 값을 쪼개어 한 번에 여러 변수에 초기화 할 수 있게 해 주는 코틀린 문법이다.
  • 문법 형태:
  •  
kotlin

val P = Point(10, 20)
val (x, y) = P   // x = 10, y = 20

println (x)
>> 10
println (y)
>> 20

1. 구조 분해 선언이란?

  • 구조 분해 선언이 일반 변수 선언과 비슷해 보이지만 .. 좌변에 여러 변수를 괄호로 묶고, 우변에 분해할 객체를 지정한다는 점이 다르다.
  • val (a, b) = obj → obj 내부의 component1() 결과를 a에, component2() 결과를 b에 할당한다.

2. 왜 가능한가?

 

  • 컴파일러가
kotlin val (a, b) = p
  • 를 만나면 내부적으로
  • kotlin
    val a = p.component1() // 첫 번째 값
    val b = p.component2() // 두 번째 값
  • 를 자동으로 생성하게되는데
  • 이때 호출되는 componentN() 함수는 반드시 operator fun componentN(): 타입 으로 선언되어 있어야 한다.

 


componentN 함수 자동 생성

  • data 클래스의 경우, 주 생성자 프로퍼티마다 컴파일러가 component1(), component2()… 를 자동으로 만들어 준다.
  • data class Point(val x: Int, val y: Int)
    // → 자동으로 operator fun component1() = x, component2() = y 생성
  • 이런식으로 일반 클래스에도 직접 구현할 수 있도 있다.
class Point(val x: Int, val y: Int) {
    operator fun component1() = x
    operator fun component2() = y
}

함수에서 여러 값 반환하기

  • 여러 값을 묶어 반환할 때는 data class 또는 Pair·Triple 을 활용하면 구조 분해 선언을 통해 손쉽게 풀어쓸 수 있다고 하네요

<구조 분해 선언을 사용해 여러 값 반환하기>

kotlin
복사
data class NameComponents(val name: String, val extension: String)

fun splitFilename(fullName: String): NameComponents {
    val result = fullName.split('.', limit = 2)
    return NameComponents(result[0], result[1])
}

val (name, ext) = splitFilename("example.kt")
println(name)  // example
println(ext)   // kt

  • Pair<String, String> 사용 시에는
kotlin

fun splitFilename(fullName: String): Pair<String, String> {
    val parts = fullName.split('.', limit = 2)
    return parts[0] to parts[1]
}
  • 처럼 first·second 대신 component1()·component2() 로 바로 분해!

배열·컬렉션에서의 구조 분해

  • 코틀린 표준 라이브러리는 앞 5개 요소에 대해 component1()…component5() 를 제공한다.
  • 또한 Pair, Triple 에도 componentN() 이 정의되어 있다.
kotlin
복사
val list = listOf(1, 2, 3)
val (a, b, c) = list  // a=1, b=2, c=3


구조 분해 선언과 루프

  • 변수 선언이 가능한 곳이면 어디서나 사용할 수 있으며, 특히 Map 순회 시 매우 유용하다고 합니다
kotlin
복사
fun printEntries(map: Map<String, String>) {
    for ((key, value) in map) {
        println("$key -> $value")
    }
}

val map = mapOf("Oracle" to "Java", "JetBrains" to "Kotlin")
printEntries(map)
// Oracle -> Java
// JetBrains -> Kotlin

  • 내부적으로는
    1. map.iterator() 호출 → Map.Entry 순회자 반환
    2. 각 Map.Entry 에 대해 component1() (key), component2() (value) 호출
kotlin

for (entry in map.entries) {
    val key = entry.component1()
    val value = entry.component2()
    // …
}

주요 활용 사례

  1. 함수에서 여러 값 반환
    • Pair, Triple, data class 활용
  2. 컬렉션 순회
    • for ((k, v) in map)
  3. 고정 길이 리스트 분해
    • 최대 5개 요소까지 지원

++

  • componentN() 이 정의되지 않은 객체는 분해할 수 없다.
  • 분해할 변수 개수가 많아지면 오히려 가독성이 떨어질 수 있으니, 필수적인 경우에만 사용하는게 좋다.

위와 같이, “객체 → componentN 호출 → 변수 초기화” 의 흐름을 이해하면 코드를 더욱 간결하고 읽기 좋게 작성할 수 있는 장점이 있다.