Kotlin Koans - Introduction / Lambdas

이준영·2020년 12월 11일
0

Kotlin Koans

목록 보기
9/9
post-thumbnail

문제

fun containsEven(collection: Collection<Int>): Boolean =
        collection.any { TODO() }

Kotlin supports functional programming. Learn about lambdas in Kotlin.

Pass a lambda to the any function to check if the collection contains an even number. The any function gets a predicate as an argument and returns true if there is at least one element satisfying the predicate.

풀이

fun containsEven(collection: Collection<Int>): Boolean =
        collection.any { it % 2 == 0 }

이번 문제는 컬렉션이 짝수를 가지고 있는지 확인하는 람다를 any 함수에 전달하는 것이었습니다.

함수를 호출할 때 람다가 유일한 인자인 경우, 괄호(())를 생략할 수 있고 람다 표현식을 괄호 밖에 위치시킬 수 있습니다. 또한 람다 표현식이 하나의 매개변수만 가지는 경우, 매개변수와 -> 기호를 생략할 수 있습니다. 이때 매개변수는 암묵적으로 it 라는 이름으로 선언, 사용할 수 있습니다.

any 함수는 술어(predicate)를 인자로 받고 컬렉션의 원소 중 하나라도 술어(predicate)를 만족하면true 를 반환합니다. 이번 문제에서는 짝수가 하나라도 존재하면 true 를 반환해야 하기 때문에, 짝수이면 참을 반환하는 로직을 람다로 넘겨주면 됩니다.

정수를 2로 나눈 나머지가 0일 경우 짝수이므로 it % 2 == 0 을 람다로 넘겨주면 됩니다.

학습 내용

Higher-Order Functions and Lambdas

Lambda Expressions and Anonymous Functions

람다 표현식(Lambda expression)과 익명 함수는 선언되지 않고 표현식으로 즉시 전달되는 함수 리터럴(function literal)입니다. 아래의 예시를 보겠습니다:

max(strings, { a, b -> a.length < b.length })

max 함수는 고차원(higher-order) 함수로 함수 값을 두 번째 인자로 가집니다. 두 번째 인자는 그 자체가 함수인 표현식인데, 이 함수는 아래에 명명된 함수와 동일한 함수 리터럴입니다.

fun compare(a: String, b: String): boolean = a.length < b.length
Lambda expression syntax

람다 표현식(lambda expression)의 전체 구문 형태(full syntactic form)는 아래와 같습니다:

val sum: (Int, Int) -> Int = { x: Int, y: Int -> x + y }

람다 표현식은 항상 중괄호({})로 감싸져 있습니다. 전체 구문 형태(full syntactic form)에서 선언된 매개변수는 중괄호 안으로 들어가고 부가적으로 타입을 표기합니다. 본문은 -> 기호 뒤에 옵니다. 람다의 추론된 반환 타입이 Unit이 아니라면, 람다 본문 안에 있는 마지막(또는 아마도 단 하나의) 표현식은 반환 값으로 처리됩니다.

모든 부가적인 표기를 덜어낸다면, 아래와 같은 형식입니다:

val sum = { x: Int, y: Int -> x + y }
Passing trailing lambdas

Kotlin에는 이러한 컨벤션이 있습니다: 함수의 마지막 매개변수가 함수라면, 해당 인수로 전달될 람다 표현식은 괄호 밖에 위치할 수 있습니다:

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

이와 같은 문법을 trailing lambda라고 합니다.

함수를 호출할 때 람다가 유일한 인자라면, 괄호를 완전히 생략할 수 있습니다:

run { println("...") }
it: implicit name of a single parameter

람다 표현식이 오직 하나의 매개변수만 가지는 것은 매우 일반적입니다.

만약 컴파일러가 시그니처(signature) 자체를 파악할 수 있는 경우, 유일한 매개변수를 선언하지 않고 -> 기호도 생략할 수 있다. 이 때, 매개변수는 암묵적으로 it 라는 이름으로 선언됩니다:

ints.filter { it > 0 } // this literal is of type '(it: Int) -> Boolean'

정리하며

Kotlin에는 함수 리터럴로 람다 표현식(lambda expression)과 익명 함수(anonymous function)이 있습니다. 람다 표현식은 중괄호로 감싸져 있으며, 함수의 마지막 매개변수가 함수라면 해당 인수로 전달될 람다 표현식은 괄호 밖에 위치할 수 있습니다.

또한 함수를 호출할 때 람다가 유일한 인자라면 괄호를 완전히 생략할 수 있으며, 람다 표현식이 가지는 매개변수가 한 개라면 it 라는 이름의 변수를 암묵적으로 사용할 수 있습니다.

참고 자료

Kotlin Reference - Functions and Lambdas / Higher-Order Functions and Lambdas

[Kotlin] 고차원 함수와 람다(Higher-Order Function and Lambdas) - devlog of ShinJe Kim

코틀린(Kotlin) : 고차함수 와 람다 (Higher-Order Functions and Lambdas) - 조용한 담장

profile
growing up 🐥

0개의 댓글