분리 선언

때로는 객체를 여러 변수로 분리하는 것이 편

val (name, age) = person

이 구문을 분리 선언(destructuring declaration)이라고 한다.

println(name)
println(age)

이 분리 선언은 다음 코드로 컴파일된다

val name = person.component1()
val age = person.component2()

component1()component2() 함수는 Kotlin에서 널리 사용되는 규칙의 예이다 (+, *, for-loops 연산자 참조). 분리 선언의 오른쪽에 있는 것은 필요한 수의 component 함수를 가지고 있으면 된다.

분리 선언에서 componentN() 함수를 사용하려면 operator 키워드를 표시해야한다

분리 선언은 for-loops 에서도 동작한다

for ((a, b) in collection) { ... }

변수 a, b에 component1(), component2()의 반환값을 갖는다

Example: 함수에서 2개의 값을 반환

간단한 방법은 데이터 클래스를 선언하고 인스턴스를 반환하는 것이다

data class Result(val result: Int, val status: Status)
fun function(...): Result {
    // 계산

    return Result(result, status)
}

// 이제, 이 암수를 사용:
val (result, status) = function(...)

데이터 클래스는 componentN() 함수를 자동으로 선언하기 때문에 여기서 선언을 분리해야한다

NOTE: 표준 클래스 Pair를 사용하고 function()Pair<Int, Status>를 반환하도록 할 수 있지만, 데이터 이름을 올바르게 지정하는 것이 좋다

Example: 분리 선언과 맵

맵을 탐색하는 좋은 방법은 다음과 같다

for ((key, value) in map) {
   // 키와 값으로 무엇가한다
}

이 작업을 위해서 아래 조건이 충족되어야 한다

  • iterator() 함수를 제공
  • 각 요소를 component1()component2() 함수를 젲공하는 페어로 제공해야한다.

실제로 표준 라이브러리는 다음과 같은 확장을 제공한다.

operator fun <K, V> Map<K, V>.iterator(): Iterator<Map.Entry<K, V>> = entrySet().iterator()
operator fun <K, V> Map.Entry<K, V>.component1() = getKey()
operator fun <K, V> Map.Entry<K, V>.component2() = getValue()

따라서 맵 (물론 데이터 클래스의 인스턴스 콜렉션)을 사용하는 for-loops 에서 자유롭게 분리 선언을 사용할 수 있다

미사용 변수는 밑줄 (1.1 이후)

분리 선언에 변수가 필요하지 않으면 밑줄을 사용할 수 있다

val (_, status) = getResult()

람다에서 분리 (1.1 이후)

람다 파라미터에 대해 분리 선언 구문을 사용할 수 있다. 람다가 Pair 타입 (Map.Entry 또는 적절한 componentN 함수를 가지는 다른 타입)의 파라미터를 가지고 있다면 괄호안에 넣음으로 하나가 아닌 여러개의 새로운 파라미터를 도입할 수 있다

map.mapValues { entry -> "${entry.value}!" }
map.mapValues { (key, value) -> "$value!" }

두 개의 파라미터를 선언하고 파라미터 대신 분리 페어를 선언하는 것의 차이점에 유의하자

{ a -> ... } // 하나의 파라미터
{ a, b -> ... } // 두 개의 파라미터
{ (a, b) -> ... } // 분리된 Pair
{ (a, b), c -> ... } // 분리된 Pair와 다른 파라미터

분리된 파라미터가 사용되지 않는 경우 밑줄로 대체하여 이름을 만들지 않도록 할 수 있다

map.mapValues { (_, value) -> "$value!" }

전체 분리된 파라미터 또는 특정 요소의 유형을 별도로 지정 가능

map.mapValues { (_, value): Map.Entry<Int, String> -> "$value!" }

map.mapValues { (_, value: String) -> "$value!" }

results matching ""

    No results matching ""