<고차함수 higher-order function>
고차함수란 함수를 마치 클래스에서 만들어 낸 '인스턴스처럼' 취급하는 방법인데요
함수를 '파라미터'로 넘겨 줄 수도 있고 '결과값으로 반환'받을 수도 있는 방법입니다
즉, 다른 함수를 인자로 받거나 함수를 반환하는 함수입니다!
코틀린에서는 모든 함수를 고차함수로 사용 가능합니다
fun main() {
b(::a)
}
fun a (str: String) {
println("$str 함수 a")
}
fun b (function: (String) -> Unit) {
function("b가 호출한")
}
/* 출력
b가 호출한 함수 a
*/
a라는 함수를 만들어 문자열을 파라미터로 받고 있습니다
그리고 파라미터로 받은 문자열 뒤에 '함수 a' 라고 출력합니다
그리고 b라는 함수를 만들어 함수 a를 고차함수 형식의 파라미터로 받을 수 있도록 만들었습니다
함수를 받을 파라미터의 이름은 function으로 하고 자료형은 a의 함수의 형식을 넘겨받을 수 있도록 해야합니다
이때 함수의 형식을 자료형으로 나타내기 위해서는
괄호 안에 함수가 받을 파라미터의 자료형을 나열하고, -와 >로 화살표를 만든 뒤 (->) 함수의 반환형을 써주면 됩니다
위에서 함수 a는 문자열을 받고 반환형은 없는 함수이므로 다음과 같이 나타낼 수 있습니다
(String) -> Unit
이렇게 하면 기술한 형태와 같은 형식의 함수는 모두 파라미터로 받을 수 있습니다!
그리고 함수 b에서는 받아온 함수 a를 실행하되 문자열로 'b가 호출한' 이라는 값을 넘겨줍니다
이제 main 함수에서는 b를 호출하되 함수 a를 파라미터로 넘겨주는데요
고차함수 형태로 넘기려면 함수 이름 앞에 콜론 두개(::)를 붙여주면 됩니다
( ::는 일반 함수를 고차 함수로 변경해주는 연산자입니다)
위 코드를 실행해보면
1. main 함수가 a 함수를 b 함수에 파라미터로 넘겼고
b(::a)
2. b 함수는 받아온 a 함수에 "b가 호출한" 이라는 값을 넘겨서 호출하였습니다
function = a
function("b가 호출한")
3. 최종적으로 a 함수가 실행되면서 "b가 호출한 함수 a" 라는 문자열이 출력되는 것을 확인할 수 있습니다
str = "b가 호출한"
println("$str 함수 a")
그런데 이때 파라미터로 넘길 함수를 람다식으로 표현하는 람다함수라는 것을 사용할 수 있습니다
<람다함수 lambda function>
람다함수란 이름이 없어도 함수 역할을 하는 익명 함수로 보통 한번 사용되고 재사용되지 않는 함수를 만들 때 많이 사용합니다
위에서 만들었던 함수 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가 호출한")
}
/* 출력
b가 호출한 함수 a
b가 호출한 람다함수
*/
람다함수는 일반함수와 달리 그 자체가 고차함수이기 때문에 별도의 연산자 없이도 변수에 담을 수 있습니다
변수 c를 만들고 콜론 뒤에 위에서 사용했던 함수의 형식을 써주었습니다 ( (String) -> Unit )
일반적인 변수에 자료형을 쓰듯 그 자리에 함수의 형식을 쓴 것입니다!
그리고 뒤에 실제 동작할 람다식 부분을 구현해주었습니다
이퀄(=) 뒤에 중괄호를 붙이고 파라미터로 받아온 문자열을 매칭해 줄 변수 이름을 써줍니다
이때 원래는 콜론을 쓰고 자료형을 적는게 기본 형태이지만
( val v: (String) -> Unit = {str: String} )
여기에서는 함수의 형식을 기술한 자료형에 이미 파라미터의 자료형이 기술되어 있으므로 자료형이 자동으로 추론되므로 생략해주었습니다
이제 이 파라미터로 동작시킬 구문을 기술해주면 됩니다
함수의 형식에서와 같이 화살표 형태로 써준 후 파라미터로 받아온 문자열 뒤에 '람다함수'라고 출력해주도록 하였습니다
그리고 이제 main 함수에서 함수 b에 람다함수 c를 넘겨 실행해보면
(람다함수는 그 자체가 고차함수이기 때문에 연산자 없이 바로 b(c)로 호출 가능!)
위에서 실행했던 것과 동일한 구조로 "b가 호출한 람다함수" 라는 문자열이 출력되는 것을 확인할 수 있습니다
람다함수 역시 변수에 할당할 때는 타입추론 기능을 이용하여 좀 더 축약하여 기술할 수도 있습니다
val c = { str: String -> println("$str 람다함수")}
함수의 형식을 적지 않고 바로 중괄호 안에 직접 파라미터의 자료형만 써주면
파라미터와 리턴값을 자동으로 추론하여 이에 맞는 함수 형식의 객체로 변수에 저장해줍니다
( (String) -> Unit 자료형으로 저장됨 )
고차함수와 람다함수를 사용하면 함수를 일종의 변수로 사용할 수 있다는 편의성이 있습니다
<고차함수와 람다함수> 포스팅은 여기서 마치도록 하겠습니다!
*위 글은 유튜브 테크과학! DeMo님의 강좌를 참고하여 작성하였습니다
'Kotlin' 카테고리의 다른 글
[Kotlin] 오브젝트 Object (0) | 2023.07.27 |
---|---|
[Kotlin] 스코프 함수 (0) | 2023.07.26 |
[Kotlin] 변수, 함수, 클래스의 접근범위와 접근제한자 (0) | 2023.07.24 |
[Kotlin] 코틀린 프로젝트의 구조 (0) | 2023.07.23 |
[Kotlin] 10. 오버라이딩과 추상화 (0) | 2023.07.20 |