본문 바로가기

Kotlin

[Kotlin] 4. 람다 - with/apply

#with/apply (수신 객체 지정 람다)

with/ apply ?

  • 코틀린 표준 라이브러리 함수
  • 수신 객체 지정 람다를 사용하는 함수

수신 객체 지정 람다(lambda with receiver) 란? 

  • 람다 안에서 어떤 객체의 함수를 객체 이름을 명시하지 않고 사용하는 람다
  • 어떤 객체를 사용할지 미리 정해줘야 함 (이 때 이 객체를 '수신 객체', 'receiver'라고 한다)
  • 즉, 람다 안에서 사용할 객체를 미리 지정 해 놓고 객체 명시 없이 사용하겠다는 뜻

 


#with

1~10 홀/짝 구분 예제 - with 함수 적용 전 

strBuilder를 반복해서 호출 하는 것을 볼 수 있다

    val strBuilder = StringBuilder()
    strBuilder.append("****************홀짝****************\n")
    for (num in 1..10) {
        strBuilder.append( "$num = "+if(num%2 == 0){"짝수"}else{"홀수"} +"\n")
    }
    println("[strResult] \n $strBuilder")

1~10 홀/짝 구분 예제 - with 함수 적용 후 

with(수신객체){ }  형태로 사용

 

    val strResult = with(StringBuilder()){
        this.append("****************홀짝 with****************\n")
        for (num in 1..10) {
         this.append( "$num = "+if(num%2 == 0){"짝수"}else{"홀수"} +"\n")
        }
        this.toString()
    }
    println("[strResult] \n $strResult")
  • strBuilder를 반복해서 호출 하지 않고, 람다 안에서 바로 사용 할 수 있다(람다의 수신 객체로 strBuider가 지정이 됐기 때문이다)
  • 예제처럼 'this' 키워드로 접근할 수도 있지만 생략도 가능하다
  • with 함수는 인자를 2개인 함수이다( 첫번째 : receiver / 두번째 : 람다 )
  • 마지막 인자가 람다면 소괄호 밖으로 빼낼수 있는 특성을 사용한다
  • 람다 코드의 마지막 식을 반환한다

#apply

with와 거의 동일하다

차이점은 with는 람다 코드의 마지막 식을 반환 하지만, apply는 전달된 수신객체를 반환 한다는 차이점

 

with 예제를 apply로 적용한 모습

수신객체.apply{ }  형태로 사용

val strResult :StringBuilder = StringBuilder().apply {
    this.append("****************홀짝 apply****************\n")
    for (num in 1..10) {
        this.append( "$num = "+if(num%2 == 0){"짝수"}else{"홀수"} +"\n")
    }
    this.toString()
}
println("[strResult] \n $strResult")

그래서 (인스턴스 생성+ 초기화) 를 동시에 하는 데 유용하게 쓰인다 ex)webview 셋팅값 셋팅...

 

# 수신 객체 지정 람다를 사용하는 다른 함수도 있다

이렇게 수신 객체 지정 람다를 사용하는 함수는 with/apply 말고도 많음

그 중 유용한 예로 buildString 함수가 있는데 

StringBuilder를 자동으로 만들어 주고 결과로 toString() 결과를 반환해준다

생김새는 아래와 같다

@kotlin.internal.InlineOnly
public inline fun buildString(builderAction: StringBuilder.() -> Unit): String {
    contract { callsInPlace(builderAction, InvocationKind.EXACTLY_ONCE) }
    return StringBuilder().apply(builderAction).toString()
}

 

예시

val toString = buildString {
    this.append("****************홀짝 buildString ****************\n")
    for (num in 1..10) {
        this.append( "$num = "+if(num%2 == 0){"짝수"}else{"홀수"} +"\n")
    }
}
println("[수신 객체 지정 람다를 사용하는 buildString 함수]\n $toString")

 

 

# 장점

  • 코드를 간결하고 가독성있게
  • 식이 본문인 함수를 만들때 유용(빌더 스타일의 함수로...)
  • fun createCustomTextView() = TextView(context).apply{ ... }​

잘못된 내용이나 궁금한 내용 있으시면 댓글 달아주세요

좋은 하루 되세요!

 

출처 : Kotlin In Action - 에이콘 출판사

(위 도서를 학습하고 개인 학습용으로 정리한 내용입니다)