본문 바로가기

# 02/코틀린

[Kotlin] 코틀린의 다양한 함수들 2

반응형

확장 함수 (extension function)

- 클래스의 멤버 함수를 외부에서 더 추가할 수 있다.


fun 확장대상.함수명(매개변수, ...) : 반환값 {

...

return 값

}



fun main() {

val source = "Hello World!"

val target = "Kotlin"

println(source.getLongString(target))

}


// String을 확장해 getLongString 추가

fun String.getLongString(target : String) : String =

if (this.length > target.length) this else target


동일한 함수가 멤버에 존재하면 항상 원본 멤버 함수가 우선 사용된다.

this는 확장 대상에 있던 자리의 문자열인 source 객체를 나타낸다.

기존의 표준 라이브러리를 수정하지 않고도 확장



중위 함수 

중위 표현법(infix notation)

- 클래스의 멤버 호출 시 사용하는 점(.)을 생략하고 함수 이름 뒤에 소괄호를 생략해 직관적인 이름을 사용할 수 있는 표현법


중위함수의 조건

- 멤버 메서드 또는 확장 함수여야 한다.

- 하나의 매개변수를 가져야 한다.

- infix 키워드를 사용하여 정의한다.



fun main() {

// 일반 표현법

// val munti = 3.multiply(10)


// 중위 표현법

val multi = 3 multiply 10

println("multi : $multi")

}


// Int를 확장해서 multiply() 함수가 하나 더 추가되었음

infix fun Int.multiply(x : Int) : Int {     // infix로 선언되므로 중위 함수

return this * x

}




재귀(recursion)란

- 자기 자신을 다시 참조

- 재귀 함수는 자기 자신을 계속 호출하는 특징


재귀 함수의 필수 조건

- 무한 호출에 빠지지 않도록 탈출 조건을 만들어 둔다. - 무한 호출에 빠지는 경우 스택 오버플로가 발생할 수 있다.

- 스택 영역을 이용하므로 호출 횟수를 무리하게 많이 지정해 연산하지 않는다.

- 코드를 복잡하지 않게 한다.



꼬리 재귀 함수 (tail recursive function)

- 스택에 계속 쌓이는 방식이 함수가 계속 씌워지는 꼬리를 무는 형태

- 코틀린 고유의 tailrec 키워드를 사용해 선언



fun main() {

val number = 4                                 // number의 값을 4000으로 설정하면 스택오버플로가 발생한다.

val result : Long


result = factorial(number)

println("Factorial : $number -> $result")

}


fun factorial(n : Int) : Long {

return if (n == 1) n.toLong() else n* factorial(n-1)

}



스택을 사용하지 않음


fun main() {

val number = 5

println("Factorial : $number -> ${factorial(number)}")

}


tailrec fun factorial(n : Int, run : Int = 1) : Long {

return if (n == 1) run.toLong() else factorial(n-1, run*n)

}

함수의 점프가 아닌 계산 루프를 돌면서 바뀌게 된다. factorial 함수를 계속 호출하는게 아니라 while 문으로 계산이 계속 일어난다.



피보나치 수열 재귀 함수

0, 1로 시작하여 n번째 수와 n+1 번째 수의 합이 n+2 번째 수가 되는 수열

- 0, 1, 1, 2, 3, 5, 8 ...


fun fibonacci(n : Int, a : Long, b : Long) : Long {

return if (n == 0) b else fibonacci(n-1, a+b, a)

}



꼬리 재귀를 이용한 피보나치 수열


fun main() {

val n = 100

val first = BigInteger("0")

val second = BigInteger("1")


println(fibonacci(n, first, second))

}


// 꼬리 재귀 함수

tailrec fun fibonacci( n : Int, a : BigInteger, b : BigInteger) : BigInteger {

return if (n==0) a  else  fibonacci(n-1, b, a+b)

}



반응형