also로 Temp 변수 없이 스왑하기

순순·2024년 9월 20일

코틀린

목록 보기
7/8

알고리즘 책을 보다가 also에 대해 알게 되었다. 특히 버블 정렬 같은 정렬 알고리즘에서 also를 사용하면 temp 변수를 두지 않아도 스왑 작업이 가능하다! 코드가 훨씬 깔끔해지고 편하다.

개념

also 는 코틀린에서 모든 객체에 기본으로 제공하는 함수이며,
속성의 변경 없이 중괄호 내 명령이 실행된다.

also 구문의 실행이 끝나야 속성이 변경된다는 점이 아주 중요하다.


간단한 예시

fun main() {
    val numbers = mutableListOf(1,2,3)
    numbers
        .also { println("Before adding: $it") } // add 호출 전 리스트 상태
        .add(4)
        .also { println("After adding: $numbers")} // // add 호출 후 리스트 상태
}

출력 결과

Before adding: [1, 2, 3]
After adding: [1, 2, 3, 4]

리스트에 값을 추가하기 전후 상태를 출력해보았다. 리스트의 속성은 add(4) 호출 이후에만 변경되는 것을 볼 수 있다.


also를 이용한 스왑 예시

이제 also를 활용하여 temp 변수를 사용하지 않고 스왑하는 방법을 살펴보자. also가 실행되는 시점에서는 값이 변하지 않으므로, 원래 값인 s[end] = s[start] 가 실행된다.

package org.example
fun reverseString(s: CharArray) : Unit {
    var start = 0
    var end = s.size - 1

    // 서로 중앙으로 이동해 나가다 겹쳐지는 지점에 도달하면 종료
    while (start < end) {
        println("A start : ${s[start]}, end : ${s[end]}")

        // also 를 이용해 스왑
        s[start] = s[end].also {
            s[end] = s[start]
            println("B start : ${s[start]}, end : ${s[end]}")
        }
        println("C start : ${s[start]}, end : ${s[end]}")

        start++
        end--
    }
    println("D start : ${s[start]}, end : ${s[end]}")
}

fun main() {
    reverseString(charArrayOf('a', 'b', 'c'))
}

출력 결과

A start : a, end : c
B start : c, end : a
C start : c, end : a
D start : b, end : b
  • also를 사용하여 스왑한 시점부터 start는 'c', end는 'a'로 바뀌었다
  • also 블록을 벗어난 이후에도 start는 'c', end는 'a'로 유지된다
  • 중앙에 위치한 'b'는 스왑하지 않으므로 그대로 남아 있다.

결론

also는 블록 내에서 s[start]의 값이 변하기 전 상태를 유지하므로 temp 변수 없이 교환이 가능하게 만들어준다.

profile
플러터와 안드로이드를 공부합니다

0개의 댓글