수신 객체 지정 람다
수신 객체를 명시하지 않고 람다의 본문 안에서 다른 객체의 메서드를 호출할 수 있게 한다.
with 라이브러리 함수
with를 사용하여 어떤 객체의 이름을 반복하지 않고도 그 객체에 대해 다양한 연산을 수행할 수 있다.
with 사용 전
/** 매번 result 반복 사용 */
fun alphabet1() : String {
val result = StringBuilder()
for (letter in 'A'..'Z') {
result.append(letter)
}
result.append("\nNow I know the alphabet!")
return result.toString()
}
fun main() {
println(alphabet1())
}
with 사용 후
fun alphabet2() : String {
val stringBuilder = StringBuilder()
/* 파라미터는 2개다. 첫번째는 StringBuilder, 두번째 람다 */
return with(stringBuilder) { /* 메서드를 호출하려는 수신 객체를 지정한다. */
for (letter in 'A'..'Z') {
this.append(letter) /* this를 명시해서 앞에서 지정한 수신 객체의 메서드를 호출한다. */
}
append("\nNow I know the alphabet!") /* "this"를 생략하고 메서드를 호출한다. */
this.toString() /* 람다에서 값을 반환한다. */
}
}
with 함수는 첫번째 인자로 받은 객체를 두번째 인자로 받은 람다의 수신 객체로 만든다. 인자로 받은 람다 본문에서는 this를 사용해 그 수신 객체에 접근할 수 있다.
단순화
StringBuilder의 인스턴스를 만들고 즉시 with에게 인자로 넘기고, 람다 안에서 this를 사용하여 그 인스턴스를 참조한다. with가 반환하는 값은 람다 코드를 실행한 결과다. 그 결과는 람다 식의 본문에 있는 마지막 식의 값이다.
fun alphabet3() = with(StringBuilder()) {
for (letter in 'A'..'Z') {
append(letter)
}
append("\nNow I know the alphabet!")
toString() // 람다 값 반환
}
apply 확장 함수
apply는 항상 자신에게 전달된 객체(수신 객체)를 반환한다. apply는 확장 함수로 정의되어있다.
apply 사용
apply의 수신 객체가 전달받은 람다의 수신 객체가 된다.
이 함수에서 apply를 실행한 결과는 StringBuilder 객체다. 그 객체의 toString을 호출해서 String 객체를 얻는다.
fun alphabet() = StringBuilder().apply {
for (letter in 'A'..'Z'){
append(letter)
}
append("\nNow I know the alphabet!")
}.toString()
fun main(args: Array<String>) {
println(alphabet())
}
이런 apply 함수는 객체의 인스턴스를 만들면서 즉시 프로퍼티 중 일부를 초기화해야하는 경우 유용하다.
자바에서는 보통 별도의 Builder 객체가 이런 역할을 담당한다.
apply를 TextView 초기화에 사용하기
fun createViewWithCustomAttributes(context: Context) =
TextView(context).apply {
text = "Sample Text"
textSize = 20.0
setPadding(10, 0, 0, 0)
}
TextView 인스턴스를 만들고 즉시 그 인스턴스를 apply에 넘긴다.
- apply에 전달된 람다 안에서의 수신객체 : TextView
원하는대로 TextView의 메서드를 호출하거나 프로퍼티를 설정할 수 있다. 람다를 실행하고 나면 apply는 람다에 의해 초기화된 TextView 인스턴스를 반환한다. 그 인스턴스가 createViewWithCustomAttributes()의 결과가 된다.
표준 라이브러리 buildString 함수 사용
표준 라이브러리 buildString 함수를 사용하면 더 단순화할 수 있다.
buildString은 StringBuilder 객체를 만드는 일과 toString 호출해주는 일을 알아서 해준다.
- 수신 객체 지정 람다 : buildString의 인자
- 수신 객체 : 항상 StringBuilder
fun alphabet5() = buildString {
for (letter in 'A'..'Z') {
append(letter)
}
append("\nNow I know the alphabet!")
}
'Coding > Kotlin' 카테고리의 다른 글
함수형 프로그래밍이란? (with 코틀린 예제) (1) | 2023.11.22 |
---|---|
[Kotlin 기초문법] 총정리 (2) | 2022.10.29 |
[Kotlin in Action] 25. SAM 생성자 (0) | 2022.06.19 |
[Kotlin in Action] 24. 지연 계산(lazy) 컬렉션 연산 - 시퀀스(sequence) 사용 (0) | 2022.06.13 |
[Kotlin in Action] 23. 컬렉션 함수형 API (filter, map, all, any, count, find, groupBy, flatMap, flatten) (0) | 2022.06.01 |