#1 코틀린의 함수는 일급 객체다
코틀린에서는 함수를 일급 객체(First-class object)로 취급한다. 코틀린에서 함수를 일급 객체로 취급한다는 것은 함수가 다른 객체들과 동등하게 다루어지고, 다양한 연산을 적용할 수 있다는 의미를 갖는다. 그렇다면, 함수의 데이터 타입 또한 존재할 것이다. val s : String에서 s는 데이터 타입이 String인 객체인 것처럼, 이 String의 역할을 하는 함수 버전 타입 말이다.
#2 함수 타입 표현식의 문법
#2-1 기본 문법
fun myFunction(value1: Int, value2: Int): Int {
return value1 * value2 + 8
}
fun main() {
val functionReference: (Int, Int) -> Int
// 더블콜론(::)은 코틀린에서 함수, 클래스, 멤버 함수, 생성자 등을 참조하는 데에 사용하는 기호
functionReference = ::myFunction
println(functionReference(7, 9)) // 출력 결과: 71
}
함수 타입(Function types) 표현식은 (매개변수'들') -> 리턴 타입의 형태로 함수의 input과 output를 기술한다. 예를 들어 val f : (Int, Int) -> Int에서 f는 매개변수로 Int, String을 받고 return 타입은 Int인 함수다. 만약 위 코드에서 functionReference의 함수 타입 표현식이 myFunction과 달랐다면 myFunction을 참조할 수 없었을 것이다.
#2-2 매개변수가 없는 경우
val functionReference: () -> Int
매개변수가 없다면 ()와 같이 함수 타입 표현식의 괄호 안에 아무것도 넣지 않으면 된다.
#2-3 return을 하지 않는 경우
val functionReference: (Int, Int) -> Unit
함수 타입 표현식에서 함수의 return이 없는 경우 return 타입 자리에 Unit을 넣는다. Unit은 자바의 void에 대응되는 키워드다.
#2-4 매개변수도 없고 return도 하지 않는 경우
val functionReference: () -> Unit
매개변수도 없고, return도 없다면 해당 함수는 () -> Unit 타입이다.
#1에서 코틀린에서 함수를 일급 객체로 취급한다는 것은 함수가 다른 객체들과 동등하게 다루어지고, 다양한 연산을 적용할 수 있다는 의미를 갖는다고 했었다. 다음으론 함수를 다른 객체들과 동등하게 다룰 때 행해지는 다양한 연산의 예이다.
#3 함수 객체 연산
#3-1 함수를 변수에 할당할 수 있음
val functionReference: (Int) -> Int = fun(args: Int): Int {
return args + 1
}
fun main() {
val result = functionReference(2)
println(result) // 출력 결과: 3
}
/* 위 코드와 같은 동작을 하는 람다식 버전 코드
val functionReference: (Int) -> Int = { args -> args + 1 }
fun main() {
val result = functionReference(2)
println(result)
}
*/
#2-1의 코드에서처럼 변수에 함수를 할당할 수 있다. 코틀린에서 어떤 함수를 익명 함수로 쓰면서 해당 함수에 이름을 붙이면 에러(Anonymous functions with names are prohibited)가 나므로 fun 키워드 오른쪽에 함수 이름을 쓰지 않았다.
#3-2 함수를 return할 수 있음
fun add(x: Int, y: Int): Int = x + y
fun getAddFunction(): (Int, Int) -> Int {
return ::add
}
fun main() {
val submit = getAddFunction()(2, 3)
println(submit) // 출력 결과: 5
}
getAddFunction()의 return 타입은 Int형 2개를 받아 Int를 리턴하는 '함수'다.
#3-3 함수를 인자로 전달 가능
fun calculateNumbers(x: Int, y: Int, operation: (Int, Int) -> Int): Int {
return operation(x, y)
}
fun main() {
val result = calculateNumbers(4, 5, fun(args1, args2): Int { return args1 * args2 })
println(result) // 출력 결과: 20
}
/* 위 코드와 같은 동작을 하는 람다식 버전 코드
fun calculateNumbers(x: Int, y: Int, operation: (Int, Int) -> Int): Int {
return operation(x, y)
}
fun main() {
val result = calculateNumbers(4, 5) { args1, args2 -> args1 * args2 }
println(result)
}
*/
#3-1에서와 마찬가지로, 인자로 전달되는 익명 함수의 이름을 뺐다.
#4 요약
함수를 일반 데이터 객체처럼 다룰 수 있다면, 당연히 함수의 '데이터 타입' 또한 존재해야 한다.
'깨알 개념 > Kotlin' 카테고리의 다른 글
[Kotlin] Coroutines - 기초 (0) | 2024.02.07 |
---|---|
[Kotlin] 람다(Lambda) 표현식 (0) | 2024.02.01 |
[Kotlin] 함수형 인터페이스 (Single Abstract Method Interface) (0) | 2024.01.30 |
[Kotlin] 연산자 오버로딩 (Operator overloading) (0) | 2024.01.29 |
[Kotlin] 프로퍼티(Property) (0) | 2024.01.17 |