고차함수와 람다함수는 함수를 일종의 변수로 사용할 수 있게 해줄 뿐만 아니라
컬렉션의 조작이나 스코프 함수의 사용에도 도움이 되어 자주 활용하게 되는 함수들이다.
먼저 고차함수에 대해 자세히 알아보자.
고차함수는 함수를 마치 클래스에서 만들어 낸 '인스턴스'처럼 취급하는 방법이다.
즉 함수를 패러미터로 넘겨줄 수도 있고
결과값으로 반환받을 수도 있는 방법이다.
코틀린에서는 모든 함수를 고차함수로 사용 가능하다.
fun a (str : String){
println("$str 함수 a")
}
fun b (function: (String)->Unit) {
function("b가 호출한")
}
다음은 함수 b가 함수 a를 고차함수 형식의 패러미터로 받을 수 있도록 한 코드이다.
fun b (function: (String)->Unit)
function : 함수를 받을 패러미터 이름
자료형은 a 함수의 형식을 넘겨받을 수 있도록 해야한다.
함수의 형식을 자료형으로 나타내기 위해
괄호 안에 함수가 받을 패러미터 자료형을 나열하고 -> 화살표 옆에 함수 반환형을 써주었다.
이렇게 하면 기술한 형태와 같은 형식의 함수는 모두 패러미터로 받을 수 있다.
우리가 받을 함수 a는 문자열을 받고 반환형은 없는 함수이므로 괄호안에 String을 써주고
반환형에는 값이 없다는 형식인 Unit을 써주면 된다.
fun main() {
b(::a)
}
위 코드는 함수b를 호출하되 함수a를 패러미터로 넘겨주고 있다.
여기서 ::연산자는 일반 함수를 고차 함수로 변경해주는 연산자로 함수 이름 앞에 ::을 붙여주면 된다.
즉 main함수가 a함수를 b함수에 패러미터로 넘겼고
b함수는 받아온 a함수에 “b가 호출한”이라는 값을 넘겨서 호출하였다.
최종적으로 a라는 함수가 실행되면서 “b가 호출한 함수 a”라는 문자열이 출력되는 것을 확인 가능하다.
그런데 패러미터로 넘길 함수를 굳이 이름을 붙여 따로 만들 필요가 있을까?
이럴 경우 함수를 람다식으로 표현하는 람다함수를 사용하면 된다.
람다함수에 대해 알아보자.
람다함수는 일반함수와 달리 그 자체가 고차함수이므로 별도의 연산자 없이도 변수에 담을 수 있다.
fun main() {
b(::a)
val c: (String) -> Unit = { str -> println("$str 람다함수") }
b(c)
}
fun a(str: String) {
println("$str 함수 a")
}
fun b(function: (String) -> Unit) {
function("b가 호출한")
}
val c: (String) -> Unit = { str -> println("$str 람다함수") }
다음 코드는 일반적인 변수의 자료형을 쓰듯 그 자리에 함수의 형식을 쓴 것이다.
실제 동작할 람다식 부분을 ={} 에 구현한다.
str : String으로 받아온 값을 람다함수 내에서 사용할 변수이름
패러미터로 받아온 문자열을 매칭해 줄 변수 이름을 써준다.
val c:(String) -> Unit = {str : String}
위 코드가 보통 쓰이는 방법이지만 이미 패러미터의 자료형이 기술되어있어 자동추론 가능해 생략 가능하다.
다음으로 람다함수의 특별한 케이스들을 더 알아보자.
1. 람다함수도 여러 구문의 사용이 가능하다.
이 때 람다함수가 여러줄이 되는 경우 마지막 구문은 리턴 값이다.
val calculate: (Int,Int) -> Int = {a,b ->
println(a)
println(b)
a+b
}
2. 람다함수에 패러미터가 없다면 실행할 구문들만 나열하면 된다.
val a : ()->Unit = { println("패러미터가 없어요") }
3. 패러미터가 하나뿐이라면 it 을 사용한다.
패러미터가 여러개라면 람다함수 내에서 패러미터 이름을 일일이 써주었다.
그러나 하나라면 it으로 대체 가능하다.
val c: (String) -> Unit = { println("$it 람다함수") }
고차함수와 람다함수 공식문서 확인하러 가기
'Kotlin' 카테고리의 다른 글
[Kotlin] lateinit와 by lazy 비교 (2) | 2023.11.20 |
---|---|
[Kotlin] 코루틴(coroutine)(2) - 코루틴 사용 방법 (0) | 2023.11.15 |
[Kotlin] 코루틴(coroutine)(1) - 코루틴 무엇인가 (2) | 2023.10.09 |
[Kotlin] 익명객체와 옵저버 패턴 (0) | 2023.09.05 |
[Kotlin] 스코프 함수 (0) | 2023.08.16 |