728x90
구조 분해를 사용하면 복합적인 값을 분해해서 여러 다른 변수를 한꺼번에 초기화할 수 있다.
fun main(args: Array<String>) {
val p = Point(10, 20)
val (x, y) = p //x,y 변수를 선언한 다음에 p의 여러 컴포넌트로 초기화한다.
println(x)
println(y)
}
- 일반 변수 선언과 비슷하지만, =의 좌변에 여러 변수를 괄호로 묶었다는 점이 다르다
- 내부에서 구조 분해 선언은 관례를 사용한다
- 구조 분해 선언의 각 변수를 초기화하기 위해 componentN이라는 함수를 호출한다.
- N은 구조 분해 선언에 있는 변수 위치에 따라 붙는 번호이다.
- val x = p.component1(), val y = p.component2()로 변환된다
- data 클래스의 주 생성자에 들어있는 프로퍼티에 대해서는 컴파일러가 자동으로 componentN 함수를 만들어 준다.
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]) //함수에서 데이터 클래스의 인스턴스를 반환
}
fun main(args: Array<String>) {
val (name, ext) = splitFilename("example.kt") // 구조 분해 선언 구문을 사용해 데이터 클래스를 푼다
println(name)
println(ext)
}
- 구조분해 선언은 함수에서 여러 값을 반환할 때 유용하다
- 여러 값을 한꺼번에 반환해야 하는 함수가 있다면 반환해야 하는 모든 값이 들어갈 데이터 클래스를 정의하고 함수의 반환 타입을 데이터 클래스로 바꾼다.
- 구조 분해 선언 구문을 사용하면 이런 함수가 반환하는 값을 쉽게 풀어서 여러 변수에 넣을 수 있다.
data class NameComponents(val name: String, val extension: String) //값을 저장하기 위한 데이터 클래스 선언
fun splitFilename(fullName: String): NameComponents{
val (name, extension) = fullName.split('.', limit = 2)
return NameComponents(name, extension)
}
- 배열이나 컬렉션에도 componetN 함수가 있음을 알면 더 쉽게 코드 작성이 가능하다
- 무한히 componetN을 선언할 수는 없으므로 이런 구문을 무한정 사용할 수는 없지만, 그럼에도 컬렉션 구조 분해는 유용하다
- 코틀린 표준 라이브러리에서는 맨 앞의 다섯 원소에 대한 componetN을 제공한다.
- 컬렉션에 크기를 벗어나는 위치의 구조 분해 선언을 실행하면 실행 시점에 ArrayIndeOutOfBoundsexception 예외가 발생한다.
- 여섯 개 이상의 변수를 구조 분해 변수에 담으면 컴파일 오류 발생
- 표준 라이브러리의 Pair나 Triple 클래스를 사용하면 함수에서 여러 값을 더 간단하게 반환할 수 있다.
- Pair나 Triple은 그 안에 담겨있는 원소의 의미를 말해주지 않아 경우에 따라 가독성이 떨어질 수 있지만, 직접 클래스를 작성할 필요가 없어 코드가 더 단순해진다.
구조 분해 선언과 루프
함수 본문 내의 선언문뿐 아니라 변수 선언이 들어갈 수 있는 장소 어디든 구조 분해 선언을 사용할 수 있다.
fun printEntries(map: Map<String, String>) {
for ((key, value) in map) { //루프 변수에 구조 분해 선언을 사용
println("$key -> $value")
}
}
fun main(args: Array<String>) {
val map = mapOf("Oracle" to "Java", "JetBrains" to "Kotlin")
printEntries(map)
}
- 두 가지 코틀린 관례를 사용한다.
- 하나는 객체를 이터레이션 하는 관례, 다른 하나는 구조 분해 선언이다
- 코틀린 표준 라이브러리에는 맵에 대한 확장 함수로 iterator가 들어있다.
- iterator는 맵 원소에 대한 이터레이터를 반환한다.
- 자바와 달리 코틀린에서는 맵을 직접 이터레이션 할 수 있다.
- 코틀린 표준 라이브러리에는 Map.Entry에 대한 확장 함수로 component1, 2를 제공한다.
728x90
'KotlinInAction > 연산자 오버로딩과 기타 관례' 카테고리의 다른 글
| 프로퍼티 접근자 로직 재활용: 위임 프로퍼티 (0) | 2022.08.09 |
|---|---|
| 컬렉션과 범위에 대해 쓸 수 있는 관례 (0) | 2022.08.08 |
| 비교 연산자 오버로딩 (0) | 2022.08.08 |
| 산술 연산자 오버로딩 (0) | 2022.08.08 |