[출처 - Kotlin In Action] [아래 내용들은 Kotlin In Action을 공부하면서 스스로 정리한 내용입니다]
자바의 람다에는 없는 코틀린 람다의 독특한 기능이 있습니다. 그 기능은 수신 객체를 명시하지 않고 람다의 본문 안에서 다른 객체의 메소드를 호출할 수 있게 하는 것인데, 이를 수신 객체 지정 람다라고 부릅니다.
여기서는 수신객체지정 람다를 활용하는 with와 apply에 대해 알아 보겠습니다. 이 두개는 여기서 간단한 설명을 확인 할 수 있습니다.
with
다음 코드를 보면
fun alphabet(): String {
val result = StringBuilder()
for (letter in 'A'..'Z') {
result.append(letter)
}
result.append("\nNow I know the alphabet!")
return result.toString()
}
fun main(args: Array<String>) {
println(alphabet())
}
변수 result가 반복적으로 사용되고 있습니다. (이 정도는 사용할만 하지만, code가 더 많이 사용하는 경우도 많이 있을 것입니다.) 이 예제를 wtih를 사용하여 변경하면
fun alphabet(): String {
val stringBuilder = StringBuilder()
return with(stringBuilder) {
for (letter in 'A'..'Z') {
this.append(letter)
}
append("\nNow I know the alphabet!")
this.toString()
}
}
fun main(args: Array<String>) {
println(alphabet())
}
with 함수는 인자로 받은 객체를 괄호{ }안에 람다 수신객체로 만듭니다. 인자로 받은 람다 본문에서 this를 사용하여 그 수신 객체에 접근할 수도 있습니다. 즉 위 코드에서 stringBuilder는 this로도 대체 됩니다.(this없이 수신객체를 사용할 수 도 있습니다. 위에서는 append("\nNow I know the alphabet!") 처럼)
또한, 위의 alphabet을 더 수정하여 변수 stringBuilder를 없앨 수 도 있습니다.
fun alphabet() = with(StringBuilder()) {
for (letter in 'A'..'Z') {
append(letter)
}
append("\nNow I know the alphabet!")
toString()
}
with가 반환하는 값은 람다 코드를 실행한 결과 값이며, 이 값은 람다식의 마지막 식입니다.
그리고 alphabet이 OuterClass에 포함된 메소드인데 with에서 OuterClass에 정의된 .toString을 부르고 싶다면 다음과 같이
this@OuterClass.toString
this에 레이블을 붙이면 호출 하고 싶은 메소드를 명확하게 정할 수 있습니다.
apply
apply 함수는 with와 거의 같습니다. 차이점은 apply는 수신객체를 반환하고, 확장함수로 사용된다는 점입니다. (with는 확장함수가 아닙니다.)
fun alphabet() = StringBuilder().apply {
for (letter in 'A'..'Z') {
append(letter)
}
append("\nNow I know the alphabet!")
}.toString()
위 code를 보면 apply는 확장함수로 정의되는 것을 할 수 있습니다. 그리고 그 확장함수를 호출한 인자가 수신객체가 되며, 이 수신객체가 람다의 수신객체가 됩니다.
이런 apply는 객체의 인스턴스를 만들면서 즉시 프로퍼티 중 일부를 초기화해야 한느 경우 유용하게 사용 됩니다. 자바에서는 보통 Builder 객체가 이 역할을 담당합니다.
예를 들어 android에 TextView를 만들때 다음과 같이
TextView(context).apply{
text = "Sample Text"
textSize = 20.0
}
이렇게 새로운 TextView 인스턴스를 만들고 그 즉시 그 인스턴스를 apply에 넘겨 apply의 람다에서 TextView의 프로퍼티를 바로 설정할 수 있습니다. 이렇게 람다가 실행된 결과를 통하여 apply는 람다에 의해 초기화된 TextView의 인스턴스를 반환하게 됩니다.
'2023년 이전 > kotlin' 카테고리의 다른 글
코루틴(Coroutine)이란? -1 (0) | 2020.09.12 |
---|---|
kotlin - 널이 될수 있는 타입(?), 안전 호출 연산자(?.), 엘비스 연산자(?:), 안전 캐스트(as?) (0) | 2020.03.18 |
kotlin - 자바 함수형 인터페이스 활용 (2) | 2020.03.10 |
kotlin - 시퀀스(Sequence) (0) | 2020.03.02 |
kotlin - 컬렉션 함수형 API (1) | 2020.03.02 |