-
[Kotlin] 코틀린 함수와 함수형 프로그래밍 3Kotlin/Function 2021. 9. 8. 20:47
[Kotlin/Function] - [Kotlin] 코틀린 함수와 함수형 프로그래밍 1
[Kotlin/Function] - [Kotlin] 코틀린 함수와 함수형 프로그래밍 2
함수 타입 / 수신 객체 지정 함수 타입
1. Function types
함수의 파라메터와 return형 (함수의 시그니쳐) 에 해당하는 것이 function type이다.
val onClick: () -> Unit
onClick의 function type
인자0개 return타입 Unit
() -> Unit
일반변수선언시 타입을 선언하듯이, 함수타입변수선언시 Function type을 선언하는데
Function타입 선언시의 내용
- 리턴형이 Unit인 경우 생략되어서는 안된다
- 선택적으로 receiver type(수신 객체)을 가질 수 있다 (Function literals with receiver)
A.(B) -> C
수신 객체인 A에서 호출될 수 있는 함수를 나타낸다.
함수의 파라메터는 B타입, 리턴타입은 C
밑에서 설명한다
- suspending 함수는 suspend 수식어를 붙여야 한다.
suspend () -> Unit
suspend A.(B) -> C //수신 객체 람다인 경우
- nullable한 function type을 지정하기 위해서는 바깥에 ()를 한번더 감싼후 ?를 지정한다.
- 리턴값이 함수인 경우 (고차함수를 참조하는 경우 and 고차함수가 함수를 리턴하는 경우)
return타입 부분을 ()로 감싸고 리턴하는 함수에 대한 function type을 작성
(Int) -> ( (Int) -> Unit )
(고차함수의 인자타입들) -> ( 고차함수가 리턴하는 함수의 타입의 function type )
function type안에서 function type을 한번 더 작성하고 ()로 감싼다.
//고차함수의 리턴 타입이 함수 //고차함수의 리턴 함수 타입 -> 인자 String한개 리턴타입String fun highOrder(i: Int): (String) -> String { if (i >= 0) { //0포함 양수이면 대문자로 바꾸는 함수를 리턴 return { str -> str.uppercase() } } else { //음수이면 소문자로 바꾸는 함수를 리턴 return { str -> str.lowercase() } } } fun main() { val high = ::highOrder //동일한 식 val high2: (Int) -> ((String) -> String) = ::highOrder //고차함수로부터 리턴된 일차함수 val normal = high2(3) //양수인자 -> 대문자로 바꾸는 함수 val normal2 = high2(-3) //음수인자 -> 소문자로 바꾸는 함수 val upperString: String = normal("hello") val lowerString: String = normal2("WORLD") println(upperString) println(lowerString) }
- type alias을 사용하여 자주 사용되는 function type 참조
function type의 작성이 복잡하거나 자주사용되는 경우라면 type alias를 사용할 수 있다.
typealias NoArgumentUnitReturn = (String) -> Unit fun main() { val v: NoArgumentUnitReturn = { str: String -> println(str) } v("hello") }
2. Function literals with receiver(수신 객체 함수 리터럴)
중요한 것은 아니지만 개념을 명확히 해보자.
-Funtion type
함수 타입
-Function을 인스턴스화 하는 방법
Function Literal(익명 함수, 람다표현식)
참조가능한 함수( ::함수명) 등
https://kotlinlang.org/docs/lambdas.html#function-literals-with-receiver
- Fuction type with receiver ( 수신 객체가 지정된 Function type )
일반 함수타입 앞에 수신 객체가 지정된 함수 타입
Person 클래스
class Person(val name: String, val age: Int) { }
Person 객체 수신 함수타입
val test: Person.() -> Unit
위의 수신 객체 지정(Person)함수타입의 함수를 호출할 때는 일반 함수타입의 인자제공에 추가적으로 Person객체를 맨앞의 인자로 넘겨줘야한다.
수신 객체 람다식의 단어를 통해 함수 호출시점에 Person객체를 넘겨줌으로서 람다식의 바디에서 Person객체를 this로 사용할 수 있다. 또한 this를 생략하고 Person의 프로퍼티를 참조하는 것이 가능하다.
코드를 보자.
디컴파일 코드를 확인해보자
val 변수 : 수신 객체 함수 타입 =수신 객체 지정 람다식
val 변수2 : 함수 타입 = 람다식
문법은 다르지만 모두 똑같이 Function1 인터페이스로 구현되는 것을 볼 수 있다.
(Function 인터페이스 이전 포스팅들 참고)
수신 객체 함수 타입은 확장함수 형식으로 사용해도 실제로 일반 형식으로 호출되는 것을 볼 수 있다.
그렇다면 수신 객체 지정 람다식을 왜 사용할까?
this를 생략하여 멤버를 호출할 수 있기 때문에 가독성이 좋아지고, 불필요한 코드 수고를 덜어줄 수 있다.
또한 수신 객체 지정 함수타입은 확장 함수처럼 사용될 수 있다. 확장 함수처럼 사용되어 수신 객체를 가지고 어떠한 처리를 하는 코드임을 느낄 수 있다.
또한 기본 라이브러리나 extention function등을 참조해보면 함수형 프로그래밍으로 작성된 함수가 없는게 없다.
다음 포스팅에서 scope function을 다뤄보도록 하겠다.
'Kotlin > Function' 카테고리의 다른 글
[Kotlin] 가변인자 vararg (0) 2021.12.25 [Kotlin] inline function 정리 1 (0) 2021.12.15 [Kotlin] 코틀린 함수와 함수형 프로그래밍 2 (0) 2021.09.07 [Kotlin] 코틀린 함수와 함수형 프로그래밍 1 (0) 2021.09.06 [Kotlin] Extension (Function,Property) (0) 2021.08.16