문제의 역사: 코틀린은 처음부터 "구조 분해" 메커니즘을 지원하여 객체, 컬렉션, 함수의 반환 값에서 값을 편리하게 추출할 수 있도록 하고 있습니다. 이 메커니즘은 스칼라 및 자바스크립트와 같은 언어에서 영감을 받았습니다 (ES6 구조 분해).
문제: 전통적인 객체 지향 언어에서는 여러 속성을 추출하기 위해 각각의 필드를 명시적으로 참조하거나 중간 구조를 사용해야 했기 때문에 보일러플레이트 코드가 발생합니다. 특히 루프, Map에서의 쌍 처리 또는 데이터 클래스 작업에서 불편합니다.
해결책: 구조 분해 선언을 사용하면 여러 변수를 선언하고 객체에서 값을 한 줄로 할당할 수 있으며, 이는 클래스에 구현된 컴포넌트 함수(componentN) 덕분입니다.
코드 예시:
data class Person(val name: String, val age: Int) val (n, a) = Person("Alex", 25) println("Name: $n, Age: $a") // Name: Alex, Age: 25 val map = mapOf(1 to "a", 2 to "b") for ((key, value) in map) println("$key = $value")
주요 특징:
모든 클래스를 구조 분해할 수 있나요?
아니요. componentN 메소드가 필요합니다. 데이터 클래스와 표준 쌍/삼중 이미 포함되어 있습니다. 일반 클래스의 경우 수동으로 추가할 수 있습니다.
예시:
class Point(val x: Int, val y: Int) { operator fun component1() = x operator fun component2() = y } val (cx, cy) = Point(5, 10)
componentN이 더 적은 객체를 구조 분해하려고 하면 어떻게 되나요?
변수보다 더 많은 componentN을 선언하려고 하면 컴파일러가 오류를 발생시킵니다:
data class OnlyX(val x: Int) val (x, y) = OnlyX(5) // 오류! component2()가 없습니다.
함수에서 반환 값을 구조 분해할 수 있나요?
네! 함수는 쌍(Pair), 삼중(Triple) 또는 데이터 클래스를 반환할 수 있으며, 구조 분해를 지원합니다:
fun coords() = Pair(1, 2) val (x, y) = coords()
함수에 다섯 개의 필드가 있는 데이터 클래스가 전달되며, 구조 분해가 다섯 개의 변수로 사용됩니다. 시간이 지나면서 필드가 추가되면 패턴 요구 사항에 따라 전체 로직 검토가 필요해지며, 사용되지 않는 변수가 발생합니다.
장점:
단점:
구조 분해는 2-3개의 필드를 가진 데이터 클래스에서만 사용되며 (예: x, y 좌표) 구조가 확고하게 고정된 map을 순회할 때 사용됩니다.
장점:
단점: