본문 바로가기
프로그래밍 공부흔적/Kotlin

[부스트코스][Kotlin]코틀린의 다양한 함수들

by 뷕뺙쀡 2021. 1. 28.

부스트코스 서포터즈 3기 활동으로서
코틀린 프로그래밍 기본 1/2(함수편)을 듣고 작성된 포스팅입니다


다양한 함수들의 출격!

1) 익명(anonymous) 함수

익명 함수란? 일반 함수이지만 이름이 없는 것이다. 람다식 함수에서는 return이나 break, continue처럼 제어문을 사용하기 어렵기 때문에 함수 본문에 조건식에 따라 함수를 중단하고 반환해야 하는 경우에 일반 익명 함수로 표현할 필요가 있습니다.

fun (x:Int, y:Int):Int = x + y //함수 이름이 생략된 익명 함수

2) 인라인(inline) 함수

인라인 함수란? 이 함수가 호출되는 곳에 내용을 모두 복사해 넣어 함수의 분기 없이 처리되기 때문에 코드의 성능을 높일 수 있다. 인라인 함수는 코드가 복사되어 들어가기 때문에 대개 내용은 짧게 작성한다. 인라인 함수는 람다식 매개변수를 가지고 있는 함수 형태를 권장한다.  코드가 복사되므로 내용이 많은 함수에 사용하면 코드가 늘어난다는 것을 주의해야 한다. nonline으로 람다식이 inline함수가 되는 것을 막을 수도 있다. crossinline 키워드는 비지역 반환을 금지해야 하는 람다식에 사용한다.

fun main() {
    // 인라인 함수 shortFunc의 내용이 복사되어 들어감
    shortFunc(3) { println("First call: $it") }
    shortFunc(5) { println("Second call: $it") }
}

inline fun shortFunc(a: Int, out: (Int) -> Unit) {
    println("Before calling out()")
    out(a)
    println("After calling out()")
}

/*
<출력>
Before calling out()
First call: 3
After calling out()
Before calling out()
Second call: 5
After calling out()
*/

3) 확장 함수

확장 함수란? 클래스처럼 필요로 하는 대상에 함수를 더 추가할 수 있는 함수이다. 확장 함수를 만들 때 만일 확장하려는 대상에 동일한 이름의 멤버 함수 혹은 메서드가 존재한다면 항상 확장 함수보다 멤버 메서드가 우선으로 호출됩니다.

fun main() {
    val name = "Merry"
    val age = 10
    println(name.getNameAgeIntroduce(age))
    //이름과 나이를 소개하는 문구를 출력함
    //출력:Merry is 10
}

// String을 확장해 getNameAgeIntroduce 추가
fun String.getNameAgeIntroduce(targetAge:Int):String=
    "$this is $targetAge"

4) 중위 함수

중위 표현법(infix notation)이란 클래스의 멤버 호출 시 사용하는 점(.)을 생략하고 함수 이름 뒤에 소괄호를 붙이지 않아 직관적인 이름을 사용할 수 있는 표현법입니다. 즉, 중위 함수란 일종의 연산자를 구현할 수 있는 함수를 말한다.  중위 함수는 특히 비트 연산자에서 사용하고 있다.

fun main(){
    // 중위 표현법
    val multi = 3 multiply 10
    println("$multi") //출력:30
}

// Int를 확장해서 multiply() 함수가 하나 더 추가되었음
infix fun Int.multiply(x: Int): Int {  // infix로 선언되므로 중위 함수
    return this * x
}

5) 꼬리 재귀 함수

꼬리 재귀 함수란? 코틀린에서는꼬리 재귀 함수(tail recursive function)를 통해 스택 오버플로 현상을 해결할 수 있습니다. 이것은 스택에 계속 쌓이는 방식이 아닌 꼬리를 무는 형태로 반복합니다. 이것을 사용하기 위해 코틀린 고유의 tailrec 키워드를 사용해야 합니다.꼬리 재귀를 사용하면 팩토리얼의 값을 그때 그때 계산하므로 스택 공간을 낭비하지 않아도 되므로 일반 재귀함수보다 훨씬 안전한 코드가 됩니다.

fun main() {
    val number = 5
    println("Factorial: $number -> ${factorial(number)}")
    //출력:Factorial: 5 -> 120
}

tailrec fun factorial(n: Int, run: Int = 1): Long {
    return if (n == 1) run.toLong() else factorial(n-1, run*n)
}

www.boostcourse.org/mo132

 

코틀린 프로그래밍 기본1/2(함수편)

부스트코스 무료 강의

www.boostcourse.org

 

댓글