4-1 이름없는 함수의 또 다른 형태, 람다(Lambda)!
1) 람다식 표현 예제
fun main() {
// 1) 전체 표현
val multi1: (Int, Int) -> Int = {x: Int, y: Int -> x * y}
// 2) 선언 자료형 생략
val multi2 = {x: Int, y: Int -> x * y}
// 3) 람다식 매개변수 자료형 생략
val multi3: (Int, Int) -> Int = {x, y -> x * y}
// 4) 2줄 이상의 식 - 마지막 값이 반환값이다.
val multi4: (a: Int, b: Int) -> Int = { a, b ->
println("a : $a, b : $b")
a*b
}
}
4-2 고차함수와 람다식의 이해 (1)
1) 값에 의한 호출
- 람다식 반환값 사용
fun main() {
val result = callByValue(lambda())
println(result)
}
fun callByValue(b: Boolean): Boolean {
println("callByValue function")
return b
}
val lambda: () -> Boolean = {
println("lambda function")
true
}
2) 이름에 의한 호출
- 람다식 사용
fun main() {
val result = callByName(otherLambda)
println(result)
}
fun callByName(b: () -> Boolean): Boolean {
println("callByName function")
return b()
}
val otherLambda: () -> Boolean = {
println("otherLambda function")
true
}
3) 다른 함수의 참조에 의한 호출
- 일반 함수를 람다식으로 사용
fun main() {
val res1 = funcParam(3, 2, ::sum)
println(res1)
hello(::text)
val likeLambda = ::sum
println(likeLambda(6,6))
}
fun sum(a: Int, b: Int) = a + b
fun text(a: String, b: String) = "Hi! $a $b"
fun funcParam(a: Int, b: Int, c: (Int, Int) -> Int): Int {
return c(a, b)
}
fun hello(body: (String, String) -> String): Unit {
println(body("Hello", "World"))
}
4-2 고차함수와 람다식의 이해 (2)
1) 매개변수가 없는 람다식
fun main() {
noParam({ "Hello World!" })
noParam { "Hello World!" } // 소괄호 생략 가능
}
fun noParam(out: () -> String) = println(out())
2) 매개변수가 한 개인 람다식
fun main() {
oneParam({ a -> "Hello World! $a" })
oneParam { a -> "Hello World! $a" } // 소괄호 생략 가능
oneParam { "Hello World! $it" } // it으로 대체 가능
}
fun oneParam(out: (String) -> String) {
println(out("OneParam"))
}
3) 매개변수가 두 개 이상인 람다식
fun main() {
moreParam { a, b -> "Hello World! $a $b"} // 매개변수명 생략 불가
moreParam { _, b -> "Hello World! $b"} // 원하는 매개변수만 사용 가능
}
fun moreParam(out: (String, String) -> String) {
println(out("OneParam", "TwoParam"))
}
4-3 다양한 함수의 출격1! (익명함수, 인라인 함수)
fun main() {
// 익명 함수 - 람다식과 매우 흡사
val add1 = fun(x: Int, y: Int) = x + y
println(add1(1, 2))
val add2 = {x: Int, y: Int -> x + y}
println(add2(1, 2))
shortFunc(4) {
println("a : $it")
}
}
// 인라인 함수 - 함수를 호출하는 것이 아닌, 호출된 곳에 복사되어 실행된다.
// 함수 호출이 없기 때문에 코드의 성능을 높일 수 있다.
inline fun shortFunc(a: Int, out: (Int) -> Unit) {
println("Before calling out()")
out(a)
println("After calling out()")
}
4-3 다양한 함수의 출격2! (인라인 함수, 확장 함수)
1) 인라인 함수 일부 제한
fun main() {
shortFunc(4) {
println("a : $it")
}
}
// 인라인 함수 제한 (일부)
inline fun shortFunc(a: Int, noinline out: (Int) -> Unit) {
println("Before calling out()")
out(a)
println("After calling out()")
}
2) 비지역 반환 제한
- inline 함수식에서 out 람다식에 return을 넣으면 shortFunc 함수 자체가 같이 종료되기 때문에 이를 방지하기 위해 crossinline이라는 keyword를 넣어 람다식 return을 금지한다.
fun main() {
shortFunc(4) {
println("a : $it")
// return
}
}
inline fun shortFunc(a: Int, crossinline out: (Int) -> Unit) {
println("Before calling out()")
out(a)
println("After calling out()")
}
3) 확장 함수
fun main() {
val source = "Hello World!"
val target = "Kotlin"
// 확장함수 사용
println(source.getLongString(target))
}
// 문자열의 길이가 더 긴 문자열을 반환하는 함수를 확장
fun String.getLongString(target: String): String =
if (this.length > target.length) this else target
4-3 다양한 함수의 출격3! (중위함수, 꼬리재귀 함수)
1) 중위함수
- .과 ()를 생략하는 함수
fun main() {
val multi = 3 multiply 10 // 3.multiply(10)
println(multi)
}
infix fun Int.multiply(x: Int): Int {
return this * x
}
2) 꼬리 재귀 함수
- 스택 오버플로 현상 방지
fun main() {
val number = 5
println("Factorial: $number -> ${factorial(number)}")
}
tailrec fun factorial(n: Int, run: Int = 1): Long {
return if (n == 1) run.toLong() else factorial(n-1, run*n)
}
'Boost Course' 카테고리의 다른 글
[코틀린 프로그래밍 기본 1] 6장 코틀린과 표준함수 (0) | 2021.07.20 |
---|---|
[코틀린 프로그래밍 기본 1] 5장 프로그램의 흐름을 제어해 보자 (0) | 2021.07.19 |
[코틀린 프로그래밍 기본 1] 3장. 마법의 요술상자, 함수의 기본 (0) | 2021.07.18 |
[코틀린 프로그래밍 기본 1] 2장. 변수와 자료형 (0) | 2021.07.17 |
[코틀린 프로그래밍 기본 1] 1장. 코틀린이란 무엇일까? (0) | 2021.07.17 |