구조 분해 선언은 코틀린에서 객체를 변수 선언에서 직접 해당 구성 요소로 "언팩"할 수 있도록 하여 코드의 가독성과 간결성을 높여줍니다.
기본적으로 구조 분해는 데이터 클래스와 컬렉션(구성 요소 함수 사용을 통해)에서 작동합니다. 이는 객체의 클래스 내에서 componentN() 함수의 사용에 기반합니다.
데이터 클래스 예제:
data class User(val name: String, val age: Int) val user = User("Oleg", 32) val (name, age) = user println(name) // "Oleg" println(age) // 32
사용자 정의 클래스 예제:
class Point(val x: Int, val y: Int) { operator fun component1() = x operator fun component2() = y } val point = Point(1, 2) val (a, b) = point
자세한 사항 및 뉘앙스:
for ((k, v) in map)을 사용하며, 여기서 k와 v는 키/값 쌍을 생성합니다.질문: "데이터 클래스가 아닌 클래스에 대해 구조 분해를 사용할 수 있나요? 그리고 그 요구 사항은 무엇인가요?"
답변: 네. 클래스 내에 operator componentN 함수를 수동으로 정의해야 합니다. 데이터 클래스는 이를 자동으로 생성하지만, 모든 클래스는 이를 명시적으로 제공할 수 있습니다.
예제:
class Pair<A, B>(val first: A, val second: B) { operator fun component1() = first operator fun component2() = second } val p = Pair(1, "q") val (a, b) = p
사례
프로젝트에서 Map과 함께 구조 분해를 사용했지만, 구조 분해가 모든 반복 가능한 컬렉션에서 사용 가능하다고 잘못 가정했습니다. 그 결과, List에 대해 "ComponentN이 없습니다" 오류가 발생하여 여러 구성 요소가 예상되었지만 하나만 존재하여 애플리케이션이 충돌했습니다.
사례
한 모듈에서 사용자 정의 클래스에 구조 분해가 적용되었지만 리팩토링 후 operator
componentN함수를 추가하는 것을 잊어버렸습니다; 결과적으로 코드는 컴파일되었지만 런타임에NoSuchMethodError가 발생하여 생산 서비스가 중단되었습니다.
사례
데이터 클래스가 수정되어 속성이 재정렬되었지만 기존의 구조 분해 선언은 변경되지 않았습니다. 결과적으로 값이 잘못된 변수에 할당되어 생산에서 심각한 비즈니스 로직 오류가 발생했습니다.