Notice
Recent Posts
Recent Comments
Link
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | |||||
3 | 4 | 5 | 6 | 7 | 8 | 9 |
10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 | 18 | 19 | 20 | 21 | 22 | 23 |
24 | 25 | 26 | 27 | 28 | 29 | 30 |
Tags
- 안드로이드
- Navigation
- LiveData
- Android
- HTTP
- CollapsingToolbarLayout
- 알림
- activity
- Coroutine
- AppBarLayout
- notification
- DataBinding
- BOJ
- 알고리즘
- CustomView
- onMeasure
- ViewModel
- room
- CoordinatorLayout
- View
- Behavior
- recyclerview
- kotlin
- Algorithm
- 백준
- sqlite
- lifecycle
- hilt
- 코틀린
- onLayout
Archives
- Today
- Total
개발일지
Kotlin in A..Z (9) - 다양한 함수 본문
- 익명함수
함수의 형태를 가지고 이름이 없는 함수이다.
코드
val fun0: (Int, Int) -> Int = fun(x:Int, y:Int): Int {return x + y}
println(fun0(1, 2))
결과
3
익명함수의 간단한 표현
코드
val fun0 = fun(x:Int, y:Int) = x + y
println(fun0(1, 2))
결과
3
람다식 vs 익명함수
람다식에서는 return, continue, break처럼 제어문을 사용하기 어렵기 때문이다. 하지만 익명함수는 람다식보다 가독성이 떨어지는 특징이 있기 때문에 적절히 사용하애한다.
- 인라인 함수 (inline)
인라인 함수는 함수가 호출되는 곳에 코드를 붙여넣기 때문에 함수 콜백간 오버헤드를 줄일 수 있는 장점이 있다. 하지만 너무 긴 코드를 붙여넣기 하면 코드량이 많아져 성능 저하가 일어날 수 있다.
코드
inline fun add(x:Int, y:Int) = x + y
fun main() {
println(add(1, 2))
}
결과
3
- 인라인 함수 제한하기 (noinline)
인라인 함수의 매개변수로 사용한 람다식의 코드가 너무 길거나 인라인 함수의 코드가 너무 길면 위에서 언급한 성능저하 문제가 발생할 수 있기 때문에 noinline키워드를 사용하여 매개변수로 사용되는 람다식의 인라인을 제한할 수 있다.
코드
inline fun noinlineFunction(lambda1: () -> Unit, noinline lambda2: () -> Unit) {
lambda1()
lambda2()
lambda2()
}
- 인라인 함수의 비지역 반환 (crossline)
원래 람다식은 return문을 포함할 수 없지만 inline처리된 람다식은 포함할 수 있다. 하지만 return문이 inline처리되면서 비지역 반환을 하여 예상치 못한 결과값을 반환할 수 있다.
코드
inline fun func1(lambda1:(Int) -> Unit) {
println("func1 Start")
lambda1(10)
println("func1 End")
}
fun main() {
func1() {
println("lambda1 : $it")
return
}
}
결과
func1 Start
lambda1 : 10
return문이 inline처리되면서 fun1 End를 출력하기 전에 return되는 문제가 발생 이러한 문제를 막기위해 crossinline 키워드로 비지역 반환을 금지하는 람다식을 매개변수로 받을 수 있다.
코드
inline fun func1(crossinline lambda1:(Int) -> Unit) {
println("func1 Start")
lambda1(10)
println("func1 End")
}
fun main() {
func1() {
println("lambda1 : $it")
return // crossinline으로 비지역 반환을 금지하기 때문에 return문이 들어갈 수 없음
// Kotlin: 'return' is not allowed here
}
}
- 확장함수
클래스에는 다양한 함수가 정의되어 있지만, 기존의 정의된 함수가 아닌 확장함수를 통하여 개발자가 원하는 함수를 더 추가할 수 있다.
코드
// 기존의 없던 getLongString을 String의 확장 함수로 선언함
fun String.getLongString(str: String): String {
return if(this.length >= str.length) {
this
} else {
str
}
}
fun main() {
val str1 = "가"
val str2 = "가나다"
println(str1.getLongString(str2))
}
결과
가나다
- 중위함수 (infix)
중위함수는 연산자를 구현할 수 있는 함수이다
중위함수의 조건
- 멤버 메서드 또는 확장 함수여야 한다.
- 하나의 매개변수를 가져야 한다
- infix 키워드를 사용하여 정의한다.
코드
infix fun Int.squared(indices:Int): Int {
var result = 1
for (i in 1..indices) {
result *= this
}
return result
}
fun main() {
println(2 squared 4) // 연산자 형식으로 사용할 수 있다.
}
결과
16
- 꼬리 재귀 함수 (tailrec)
재귀 함수는 자기 자신을 계속하는 함수이다. 재귀 함수는 자기 자신을 호출하면서 스택에 메모리를 쌓게되고 계속 쌓다보면 스택오버플로를 발생할 수 있다. Kotlin에서는 이러한 문제점을 해결하기 위해 꼬리 재귀 함수를 지원한다.
꼬리 재귀함수는 반환형이 □ * 함수 형태가 아닌 함수만 반환해야 한다.
일반적인 재귀함수
코드
fun factorial(n: Long): Long {
return if(n == 1L) {
1
}
else {
n * factorial(n - 1)
}
}
fun main() {
println(factorial(5))
}
결과
120
일반 재귀함수의 스택오버플로우
코드
fun factorial(n: Long): Long {
return if(n == 1L) {
1L
}
else {
n * factorial(n - 1L)
}
}
fun main() {
println(factorial(100000000))
}
결과
Exception in thread "main" java.lang.StackOverflowError
꼬리재귀함수
코드
tailrec fun factorial(n: Long, result: Long): Long {
return if(n == 1L) {
result
}
else {
factorial(n - 1, result * n)
}
}
fun main() {
println(factorial(100000000, 1))
}
결과
0 // Long의 범위를 초과하여 결과값이 이상하긴 하지만 스택오버플로를 발생하지 않음
'Kotlin (코틀린)' 카테고리의 다른 글
Kotlin in A..Z (11) - when (0) | 2020.07.15 |
---|---|
Kotlin in A..Z (10) - if문 (0) | 2020.07.15 |
Kotlin in A..Z (8) - 람다 (0) | 2020.07.11 |
Kotlin in A..Z (7) - 함수 (0) | 2020.07.11 |
Kotlin in A..Z (6) - 연산자 (0) | 2020.07.10 |
Comments