- Do it 코틀린 프로그래밍 책보고 공부한 내용입니다.
콜백함수
- 특정 이벤트가 발생하기까지 처리되지 않다가 이베트가 발생하면 즉시 호출되어 처리되는 함수
fun networkCall(onSuccess : (ResultType)->Unit, onError : (Throwable) -> Unit){
try{
onSuccess(myResult)
} catch (e: Throwable){
onError(e)
}
}
networkCall(result ->{
// 네트워크 호출 성공 시 구현
}, error->{
// 네트워크 호출에 실패 시 구현부
});
익명함수
- 일반 함수지만 이름이 없는 것
- 람다식에서는 return이나 break, continue 같은 제어문을 사용하기 어렵다.
fun(x: Int, y : Int) : Int = x + y // 함수 이름 생략된 익명 함수
val add : (Int, Int) -> Int = fun(x, y) = x + y
val result = add(10,2)
val add = fun(x : Int, y : Int) = x + y // 매개변수에 자료형을 쓰면 선언부 자료형 생략가능
val add = {x : Int, y : Int -> x+y }
인라인 함수
- 인라인 함수로 작성된 함수는 본문에 복사됩니다.
- 함수가 분기되지 않기 때문에 메모리 전환에 드는 비용이 절약됩니다.
inline fun shortFunc(a: Int, out: (Int) -> Unit){
println("Before calling out()")
out(a)
println("After Calling out( )")
}
shortFunc(3){println("First call : $it")}
shortFunc(5){println("Second call : $it")}
일부 람다식이 인라인이 되지 않도록 설정할 수 있습니다.
inline fun sub(out1 : ( )-> Unit, noinline out2 : ()->Unit){
...
}
비지역 반환
- 인라인 함수의 매개변수로 사용되는 람다식에는 return문이 사용가능합니다.
이 때, return은 inline함수가 호출되는 곳에서 return을 호출하게 되고 그대로 종료됩니다.
이를 비지역 반환(Non- local Return)이라고 합니다.
비지역 반환을 금지하기 위해서는 crossinline 키워드를 사용해야합니다.
코드 작성 단계에서 오류를 보여줘 잘못된 비지역 반환을 방지할 수 있습니다.
fun main(){
shortFunc(3){
println("First call: $it")
// return 사용 불가
}
}
// 문맥이 달라져 중첩된 람다식 함수는 인라인이 되지 않는다.
inline fun shortFunc(a : Int, crossinline out : (Int) ->Unit){
println("Before calling out( )")
nestedFunc{out(a)}
println("After calling out()")
}
fun nestedFunc(body : () ->Unit){
body()
}
확장함수
클래스처럼 필요한 대상에 함수를 더 추가할 수 있는 기능입니다.
fun String.getLongString(target: String): String =
if(this.length>target.length) this else target
위는 String 클래스에 getLongString()이라는 함수를 확장한 것입니다.
기존 클래스의 선언 구현부를 수정하지 않고 외부에서 쉽게 기능을 확장할 수 있습니다.
이름이 멤버 메서드와 동일할 경우 멤버 메서드가 우선으로 호출됩니다.
중위함수 - infix키워드
함수 호출에 점(.)을 생략하고 함수 이름 뒤에 소괄호를 붙이지 않습니다. 연산자와 같이 사용 가능합니다.
조건이 필요합니다.
1. 멤버 메서드 또는 확장 함수여야 한다.
2. 하나의 매개변수를 가져야 한다.
3. infix 키워드를 사용하여 정의한다.
infix fun Int.multiply(x : Int) : Int{
return this*x
}
//사용
val multi = 3 multiply 16
꼬리 재귀 함수 - tailrec 키워드
스택 오버플로 방지, 일반 재귀함수에서 호출이 너무 많이 쌓이는 것을 막을 수 있습니다.
계산을 먼저 하고 다음 함수가 호출됩니다. 스택에는 하나만 있는 것입니다.
//팩토리얼
tailrec fun factorial(n : Int, run : Int =1): Long{
return if(n==1) run.toLong() else factorial(n-1, run*n)
}
//피보나치
tailrec fun fibonacci(n : Int, a : BigInteger, b : BigInteger): BigInteger{
return if(n==0) a else fibonacci(n-1, b, a+b)
}
함수와 변수의 범위
- 최상위 함수는 함수 전후 어디에서든 정의해도 사용할 수 잇습니다.
- 지역 함수는 선언한 이후에 사용 가능합니다.
댓글