OSS로 공부 :: Kotlin - Trailing lambda

Kotlin-Telegram-Bot

코틀린용 텔레그램 봇 라이브러리.

Start수가 아주 높진 않아도 굉장히 잘 만들어진 라이브러리이다. 최근까지 지속적으로 업데이트를 하고 있으며 사용법도 굉장히 간단하고 쉬워서 애용한다.

사용법

1
2
3
4
5
6
fun main(args: Array<String>) {
val bot = bot {
token = "YOUR_API_KEY"
}
bot.startPolling()
}

발급받은 텔레그램 봇 API KEY를 작성하고 Bot 객체를 만들고 시작만 하면 된다.

여기서 궁금한 점

사용법을 보면 굉장히 간단해 보이는데 여기서 궁금한 점이 생겼다.

bot 객체를 만들 때 사용하는 bot { ... }은 함수인가? 아니면 람다인가? 궁금하니 빨리 코드를 까보자.

코드는 이렇게

1
fun bot(body: Bot.Builder.() -> Unit): Bot = Bot.Builder().build(body)

아. 코드를 보니 함수였다.

신기하게 생긴 함수이긴 하지만 생긴 건 분명 함수이다. 그럼 함수의 요소대로 이 함수를 분해해보자.

  • 이 함수의 이름은 bot이다.
  • 이 함수의 매개 변수의 이름은 body이며 타입은 Bot.Builder.() -> Unit이다.
  • 이 함수의 반환 타입은 Bot이다.
  • Bot.Builder.() → Unit 타입의 람다를 인수로 받고 반환은 Bot 타입bot이라는 이름의 함수이다.

이 함수의 매개 변수 타입은 람다이다. 어떤 람다를 받는지는 모르겠으나 어쨌든 람다이다. 그리고 코틀린에서 람다는 ->, { }로 구분 질 수 있다.

  • ->의 전 후로 인자와 본문으로 나뉜다.
  • { }는 람다식을 의미한다.

여기까지 정리를 해보니 사용법에서 나온 코드가 어느정도 해석이 되는 것 같다.

다시 한 번 더

1
2
3
4
5
6
fun main(args: Array<String>) {
val bot = bot {
token = "YOUR_API_KEY"
}
bot.startPolling()
}
  • val bot의 타입은 bot 함수에 의해 Bot타입이다.
  • bot 함수의 매개 변수 타입은 람다식이므로 메인에서는{ token = "..." }이라는 람다식으로 bot 함수에 인수로 넘기고 있다.

여기까지는 이제 이해가 된다. 그럼에도 아직 이상한 모양이 보인다. 찾았는가.

바로 bot 함수의 호출 형태이다.

함수 호출은 모두 알다시피 괄호 ()로 끝나야 한다. 하지만 우리가 해석하여 함수라고 정의한 bot 함수는 평범한 함수 호출과는 다르게 괄호 ()가 없고 바로 람다식이 왔다.

여기서 우리는 코틀린의 문법을 하나 배울 수 있다. 바로 Trailing Lambda이다.

Trailing Lambda

직역하면 후미진 람다?로 코틀린에서는 이렇게 정의한다.

In Kotlin, there is a convention: if the last parameter of a function is a function, then a lambda expression passed as the corresponding argument can be placed outside the parentheses

즉, 함수의 마지막 매개 변수가 함수라면 해당 인수로 전달 되는 람다식을 괄호 밖에 넣을 수 있다.

1
val product = items.fold(1) { acc, e -> acc * e }

그리고 한 가지 더 규칙이 있는데 이 규칙에 의해 사용법에서 보는 것과 같이 사용할 수 있다.

If the lambda is the only argument to that call, the parentheses can be omitted entirely

만약 람다가 함수의 유일한 인수라면 괄호를 완전히 생략할 수 있다.

1
run { println("...") }

그러므로 사용법에서 나온 것처럼 bot 함수를 호출할 때 bot { token = ... }으로 사용이 가능했던 것이다.

다음 번에는

1
fun bot(body: Bot.Builder.() -> Unit): Bot = Bot.Builder().build(body)

bot 함수의 매개 변수 타입은 람다식인데 이 람다식의 인수는 어떻게 읽는 걸까?

1
2
3
4
5
6
fun main(args: Array<String>) {
val bot = bot {
token = "YOUR_API_KEY"
}
bot.startPolling()
}

그리고 메인에서 람다식을 사용 할 때 token이라는 이름 혹은 변수는 어디서 나온 걸까?

이 두 가지 물음의 답은 단 하나이다.

그것은 바로…

댓글

Your browser is out-of-date!

Update your browser to view this website correctly. Update my browser now

×