알고리즘 책을 보다가 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를 활용하여 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는 블록 내에서 s[start]의 값이 변하기 전 상태를 유지하므로 temp 변수 없이 교환이 가능하게 만들어준다.