brunch

You can make anything
by writing

C.S.Lewis

by 서준수 Jan 05. 2018

코틀린(Kotlin) 리시버가 있는 함수 리터럴

빠르게 살펴보기

리시버가 있는 함수 리터럴 (Function Literals with Receiver)


 코틀린은 지정된 receiver 객체로 함수 리터럴을 호출 할 수 있도록 합니다. 함수 리터럴의 body내에서, 어떤 추가적인 한정자 없이 해당 receiver 객체 메서드를 호출할 수 있습니다. 마치 함수의 body 내부에 있는 receiver 객체의 멤버에 접근 가능한 확장 함수처럼요.


 그러한 함수 리터럴의 타입은 다음과 같이 receiver를 가지는 함수 타입입니다.                    


 sum : Int.(other: Int) -> Int



 와닿지 않으니 예제를 한 번 실행해보겠습니다.


fun main(args: Array<String>) {

    val sum1 : Int.(num: Int) -> Int = {this+it}

    val sum2 : Int.(Int) -> Int = {this+it}

    println(1.sum1(2))

    println(1.sum2(2))

}


3
3



 람다식은 연습겸 조금 다르게 하나 더 표기해봤습니다.


 익명 함수 문법은 직접적으로 함수 리터럴의 receiver 타입을 지정할 수 있도록 합니다. 이것은 만약에 receiver를 가지는 함수 타입의 변수를 선언하고 추후에 그 변수를 사용할 때 유용합니다.                    


fun main(args: Array<String>) {

    val sum = fun Int.(num: Int): Int = this + num

    println(1.sum(2))

}




 람다 표현식은 receiver 타입이 문맥상 유추될 수 있을 때 receiver를 가진 함수 리터럴로 사용될 수 있습니다.                    


class HTML {

    fun body() { ... }

}


fun html(init: HTML.() -> Unit): HTML {

    val html = HTML()  // create the receiver object

    html.init()        // pass the receiver object to the lambda

    return html

}



html {       // lambda with receiver begins here

    body()   // calling a method on the receiver object

}



 잘 이해가 안되네요. 


다음과 같이 보면 좀 도움이 될 것 같습니다.           


 fun main(args: Array<String>) {

    val test : (HTML.() -> Unit) = {

        println("test")

    }

    html(test)

}


class HTML {

    fun body() {

        println("HTML")

    }

}


fun html(aaa: HTML.() -> Unit): HTML {

    val html = HTML()  // receiver 객체 생성

    html.aaa()        // receiver 객체를 람다로 전달

    return html

}



//html {       // receiver가 있는 람다의 시작점

//    body()   // receiver 객체의 메소드를 호출

//}


test


브런치는 최신 브라우저에 최적화 되어있습니다. IE chrome safari