익명 함수(anonymous functions)
- 함수가 이름이 없는 것
fun (x: Int, y: Int) : Int = x + y // 함수 이름이 생략된 익명 함수
val add : (Int, Int) -> Int = fun(x, y) = x + y // 익명 함수를 사용한 add 선언
val result = add (10, 2) // add 의 사용
val add = fun( x : Int, y : Int ) = x + y
val add = { x : Int, y : Int -> x + y } // 람다식과 매우 흡사
하지만 !!
일반 익명 함수에서는 return, break, continue가 사용 가능하지만 람다식에서는 사용하기 어렵다. (라벨 표기법과 같이 사용해야 함!)
따라서 익명함수를 사용하는 것임!!
인라인(inline) 함수
- 함수가 호출되는 곳에 내용을 모두 복사
- 함수의 분기 없이 처리 -> 성능 증가
fun main ( ... ) {
sub()
sub()
}
fun sub ( ... ) {
abc
}
// main 함수에서 sub 함수를 호출할 때 호출할 때마다 분기가 일어남. 함수를 분기할 때마다 스택 프레임이 만들어진다.
fun main ( ... ) {
sub() - 본문 abc로 복사됨 구현내용이 전부 복사됨
sub() - 본문 abc로 복사됨
}
inline fun sub ( ... ) {
abc
}
// main 함수에서 sub() 호출된 부분에서 구현내용을 다 복사하는 것임. 장점은 성능 증가 단점은 구현내용이 많은 경우 함수 재사용이 많을때 코드사이즈가 커질 수 있다.
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()")
}
성능상의 이유로 인라인 함수는 일반 함수에도 사용할 수 있으나 람다식을 매개 변수로 가진 함수에 사용할 것을 추천하고 있다.
이 때 매개변수로 사용된 람다식의 내용도 복사되어 들어간다.
인라인 함수의 단점
코드가 복사되므로 내용이 많은 함수에 사용하면 코드가 늘어난다.
noinline 키워드
일부 람다식 함수를 인라인 되지 않게 하기 위해
inline을 쓰면 모든 매개변수의 람다식 내용도 복사된다.
inline fun sub(out1: () -> Unit, noinline out2 : () -> Unit) {
noinline으로 선언된 매개변수의 람다식 내용은 복사되지 않는다.
invoke()는 FunctionN을 구현하는 객체를 호출 시킬때 사용한다. - 나중에 나온다고..
비지역 반환(non-local return)
fun main() {
shortFunc(3) {
println("First call : $it")
return // 1. 의도하지 않은 반환
}
}
inline fun shortFunc (a : Int, out : (Int) -> Unit) {
println("Before calling out()")
out(a)
println("After calling out()") // 2. 이 문장은 실행되지 않음
}
비지역 반환의 금지 - crossinline으로 return 금지
fun main() {
shortFunc(3) {
println("First call : $it")
// return 사용 불가 return 쓰면 빨간줄 뜸
}
}
inline fun shortFunc (a: Int, crossinline out : (Int) -> Unit) {
println("Before calling out()")
nestedFunc { out(a) } - 함수가 겹쳐져 있으면 비지역 반환을 사용할 수 없어서 crossinline을 꼭 해줘야됨!!
println("After calling out()")
}
fun nestedFunc(body : () ->Unit) {
body()
}
nestedFunc는 인라인 되지 않고 매개변수만 인라인 된다.
람다식으로 만들어진 함수는 Function 인터페이스로 만들어지는 객체가 된다. 람다식을 많이 호출하게 되면 객체가 계속 만들어져 메모리 사용량이증가한다. 방지하기 위해 인라인으로 내부복사하여 성능을 증가할 수 있다.
'# 02 > 코틀린' 카테고리의 다른 글
[Kotlin] 안드로이드 코딩 1 (0) | 2019.07.07 |
---|---|
[Kotlin] 코틀린의 다양한 함수들 2 (0) | 2019.07.07 |
[Kotlin] 네트워크 호출 구현 람다식 활용 (0) | 2019.07.05 |
[Kotlin] 동기화를 위한 코드 구현 람다식 활용 (0) | 2019.07.05 |
[Kotlin] 다른 함수의 참조에 의한 호출 (0) | 2019.07.04 |