! 3주에 걸친 앱잼이 끝나고나서 어찌저찌 앱을 구현하기는 했지만 너무 코드가 지저분해서 가독성도 좋지 않고, 수정해야 할 부분들이 많다. 리팩토링과 클린 코드를 위해 코틀린에 대해 더 알 필요가 있다고 생각하여 공부를 했다.
고차함수와 람다 표현식을 이해하기 위해서는 일급함수에 대해 알아야 한다. 이를 위해 여러 블로그 및 사이트를 찾아봤고 코드차차라는 곳에 자세하게 기술되어 있어 이를 참고하여 공부를 진행했다. codechacha
일급함수는 객체로 취급되는 함수를 의미하고 3가지 특징을 가지고 있다.
일급함수는 함수의 객체로 취급 될 수 있다.
일급 함수는 함수 객체를 인자로 넘길 수 있다.
일급함수는 함수의 return 값이 될 수 있다.
이 3가지 특징을 코드를 통해 알아보겠습니다.
val hi: () -> String = {"hi my friend"}
위의 있는 코드에서 우리는 변수 hi에 "hi my fried"를 return하는 함수를 할당하였습니다.
val hi: () -> String = {"hi my friend"}
fun printHi(func: () -> String){
print("${func()}")
}
fun main(){
printHi(hi)
}
여기서 printHi의 경우 인자에 스트링을 리턴받는 함수를 받고 있고 실제로 String을 리턴하는 hi를 printHi의 인자로 넘겼을 때 "hi my friend"가 출력됩니다.
val hi: () -> String = {"hi my friend"}
fun printHi() : () -> String {
return hi
}
fun main(){
val returned : () -> String = printHi()
print("${returned()}")
}
printHi 함수의 경우 return 값으로 스트링을 return하는 hi라는 함수를 return합니다. 이 함수를 받아서 호출하는 returned 함수 객체를 만들어 이를 호출할 경우 "hi my friend"가 출력됩니다.
위에서 정리한 일급 함수의 특징을 잘 숙지하고 있다면 고차 함수에 대한 내용도 쉽게 이해가 가능합니다.
일급 함수의 3가지 특징 중 위의 2가지 특징을 하나라도 만족시키면 해당 함수를 우리는 고차 함수라고 부릅니다.
val hi: () -> String = {"hi my friend"}
fun printHi(func: () -> String) : () -> String {
return hi
}
fun main(){
val returned = printHi(hi)
print("${returned()}")
}
위의 코드에서 printHi라는 함수는 함수를 인자로 받고 또한 함수를 결과로 return해준다.
여기서 인자로 함수를 넘길 때에는 이름 뒤에 :() -> String과 같이 함수의 타입을 명시해 주어야 하고, 만약 인자로 두개를 넘길 경우
(Int, Int) -> String과 같이 표현이 가능하다. 추가로 return 값이 없을 경우에는 -> 다음에 Unit으로 표현을 하면 된다.
고차함수는 콜백 인터페이스를 사용할 때와 같이 구성 요소 간에 통신할 때 유용하다. 이번 차로 리팩토링 할때 사용해보면 좋을 듯(?)
이 람다 표현식을 통해 익명 클래스 및 익명 함수를 간결하게 표현할 수 있어서 매우 유용하다. 하지만 디버깅이 어렵고 무분별하게 남발할 경우 오히려 코드 가독성이 떨어지기 때문에 주의해서 사용해야 한다.
max(strings, {a, b -> a.length < b.length})
위의 코드는 고차 함수 이다. 두번째 인자로 함수가 넘겨지기 때문이다.
여기서 {a,b -> a.length < b.length}의 경우에는 다음 보여줄 compare함수와 동일한 기능을 나타낸다.
fun compare(a: String, b: String) : Boolean {
return a.length < b.length
}
이 두 가지 코드를 통해 compare라는 이름이 있는 함수를 중괄호 안에 있는 코드로 바꿔 이름이 없는 함수로 표현할 수 있음을 알 수 있다.
val sum: (Int, Int) -> Int = { x: Int, y: Int -> x + y }
람다 식은 항상 중괄호{}로 둘러 싸여 있다.
-> 기호 다음에는 함수의 body 부분이 나타난다.
-> 앞에는 함수에 전달된 매개 변수를 입력해준다.
코틀린의 규칙에 따르면 함수의 마지막 매개변수가 함수일 경우 해당 인수로 전달된 람다 표현식을 괄호 밖에 배치할 수 있다. 위의 코드인
max(Strings, {a,b -> a.length < b.length})
를 다음과 같이 나타낼 수 있다.
max(strings) {a,b -> a.length < b.length}
추가로 람다 식에서 만약 매개변수가 하나가 있을 경우에 굳이 매개변수를 선언할 필요가 없고 -> 생략하고 매개 변수를 it으로 표시를 합니다.
일단 여기까지 공부!