오늘은 코틀린의 함수에 대해서 살펴보도록하자.
함수
함수 선언 및 사용
함수 선언은 자바와는 달리
fun
을 사용해서 함수를 선언한다.
fun function(x: Int): Int {
return x * 2
}
위와 같은 함수가 있을 경우 사용법은 아래와 같다.
val result = function(2)
println(result)
쓰는 법은 일반 다른 언어와 비슷한 문법을 가지고 있다.
또한 위의 함수는 expression 으로도 나타낼 수 있다.
fun function(x: Int) = x * 2
expression으로 쓸 경우에는
return
타입을 명시해주지 않아도 되며
return
키워드는 사용하지 않아야 한다.
Infix notation
infix
키워드를 사용해서 중위(Infix) 표현으로 사용할 수 도 있다.
fun Int.multiply(x: Int): Int {
return this * x
}
위의 코드는 Int를 확장한 확장 함수이다. 간단하게 생각하면 Int 클래스의 함수를 더 추가 한다고 생각하면 되겠다.
val multiply = 3.multiply(10)
그럼 위와 같이 확장함수를 이용해서 간단하게 만든 multiply 를 사용할 수 있다. 중위 표현으로 변경하면 다음과 같다.
infix fun Int.multiply(x: Int): Int {
return this * x
}
위와 같이
infix
키워드를 사용하면 중위 표현을 사용할 수 있다.
val multiply = 3 multiply 10
Default Arguments
함수의 파라미터(인자)에 기본값을 정의해 줄 수도 있다.
fun defaultArgumentsFun(x: Int = 100, y: Int = 200) {
println(x + y)
}
위의 함수의 파라미터에는
x = 100 y = 200
으로 기본값으로 정의해 두었다.
defaultArgumentsFun()
위와 같이 사용할 수 있는데 파라미터가 없이 함수를 사용할 경우에는 기본값인 x에는 100이 y에는 200이 들어간다.
defaultArgumentsFun(100, 200)
위의 두개의 함수 사용은 같다고 볼 수 있다.
Named Parameters
함수의 파라미터는 함수를 호출 할 때 이름을 지정해 줄수 있다. 파라미터의 개수가 많거나 기본 값을 가진 경우에 사용하면 매우 유용하다.
fun namedParametersFun(x: Int = 100, y: Int = 200, z: Int) {
println(x + y + z)
}
위와 같은 함수가 정의 되어 있을 경우에도 (z는 기본값이 없다.) Named Parameters를 사용할 수 있다. 사용 법은 아래와 같다.
namedParametersFun(x = 200, z = 100)
함수를 호출할 때 해당하는 이름을 지정해주면 된다. 당연히 z의 경우에는 기본값이 없기에 무조건 넣어줘야한다.
namedParametersFun(x = 200)
위와 같이 호출 할 경우에는 컴파일 에러가 발생한다.
Unit-returning functions
Unit은 어떠한 값도 리턴 하지 않는 것을 의미한다. 자바의 void와 비슷한 의미를 갖고 있다.
Unit을 리턴할 경우에는 리턴 타입을 명시해주지 않아도 된다.
fun unitReturnFun(x: Int) : Unit{
println(x)
}
위의 코드는 Unit을 리턴하는 (리턴 값이 없는) 코드이다. 위의 코드는 Unit을 생략해도 된다.
fun unitReturnFun(x: Int) {
println(x)
}
위와 같이 사용해도 컴파일 에러가 나지 않는다.
Variable number of arguments (Varargs)
코틀린에서도 자바와 같이 가변인자를 지원한다.
public static <T> void varargsParameters(T... ts){
for(T t: ts){
System.out.println(t);
}
}
자바의 경우에는 타입뒤에
...
을 사용해서 가변인자로 만들 수 있다. 코틀린의 경우에는
vararg
키워드를 사용해서 만들수 있다. 위 자바 코드를 코틀린으로 바꾼다면 아래와 같다.
fun <T> varargsParametersFun(vararg ts: T) {
for (t in ts){
println(t)
}
}
Higher-Order Functions and Lambdas
자바와 비슷하다. 코틀린은 고차함수도 사용가능하며 람다 표현식도 가능하다. 자바8을 사용하는 개발자라면 쉽게 다가갈 수 있다.
Higher-Order Functions은 파라미터로 함수를 받거나 함수를 리턴하는 함수이다.
잠깐 언급만 하고 가자. 일급언어의 조건은 다음과 같다.
1. 함수를 변수나 데이터 구조안에 담을 수 있다.
2. 함수를 파라미터로 전달 할 수 있다.
3. 함수를 반환(리턴) 값으로 사용할 수 있다.
위의 3가지를 만족하면 일급언어가 될 수 있다. 자바8도 3가지를 만족해서 일급 언어라고 할 수 있다. 메서드 레퍼런스가 영 맘에 안들어도 일단 만족은 하니...
아래 코드를 보자.
val list = mutableListOf(1, 2, 3, 4, 5)
val doubled = list.map { i -> i * 2 }
위의 코드는 고차 함수의 간단한 예이다.
map
은 함수를 파라미터로 받고 있다. 실제 코드는 아래와 같다.
public inline fun <T, R> Iterable<T>.map(transform: (T) -> R): List<R> {
return mapTo(ArrayList<R>(collectionSizeOrDefault(10)), transform)
}
위에서 봤듯이 람다의 문법은 자바와 비슷하다. 다른 점이 있다면
()
대신
{}
감싸주는 부분이 다르다. 자바와는 조금 다르게 단일 파라미터에
it
이라는 명을 사용해서 조금더 간단하게 만들 수 있다. 위에 코드를
it
을 사용해 바꾸어 보면 다음과 같다.
val list = mutableListOf(1, 2, 3, 4, 5)
val doubled = list.map { it * 2 }
->
도 생략하고 조금더 간단해 졌다.
코틀린의 중요한 문법은 이정도로 된 듯 싶다. 아직 많긴 하지만 나머지는 공식 문서를 보면서 한번씩 해보는 것이 좋겠다.
다음시간에는 마지막으로 기타 여러 사항을 간단간단하게만 살펴보고 끝내자. 그래도 어느정도 공부는 된 듯 싶다.
필자가 한달전 쯤에 spring boot를 코틀린으로 만든 간단한 웹페이지가 있다. spring boot를 쓰는 개발자들은 한번씩 간단하게 살펴봐도 괜찮을 거 같다. 근데 워낙 자바로 만든거나 코틀린으로 만든거나 비슷한거 같다.
spring-boot-kotlin-example
위의 github에서 소스를 확인가능하다.