[코틀린기초] 7. 흐름제어

흐름제어문

  1. return

함수에서 결괏값을 반환하거나 지정된 라벨로 이동

//return 으로 값 반환
fun add(a:Int, b:Int): Int{
  return a+b
  println("이 코드는 실행되지 않습니다.")
}


//return 으로 Unit 반환

fun hello(name:String) : Unit { // Unit 키워드는 생략해도 됨. 리턴값을 명시하지 않으면 기본이 Unit
  println(name)
  return Unit // 이 부분도 생략이 가능. 
}

람다식에서 return 사용하기

fun main(){
  reFunc()
}

inline fun inlineLambda(a:Int,b:Int,out:(Int,Int) -> Unit){
  out(a,b)
}

fun retFunc(){
  println("start of retFunc")
  inlineLambda(13,3){ a,b ->
    val result = a+b
    if(result > 10) return // 여기서의 return은 비지역 반환(non local return). retFunc함수를 반환한다.
    println("result: $result")
  }
  println("end of retFunc")
}

비지역 반환을 하고 싶지 않다면 라벨을 사용한다.

fun inlineLambda(a:Int,b:Int,out:(Int,Int) -> Unit){ //1. 인라인 제거
  out(a,b)
}

fun retFunc(){
  println("start of retFunc")
  inlineLambda(13,3) lit@{ a,b -> //2. 람다식 블록의 시작 부분에 라벨지정
    val result = a + b
    if(result > 10) return@lit  //3. 라벨을 사용한 블록의 끝부분으로 반환
    println("result: $result")
  }
  println("end of retFunc") // 4. 이부분이 실행됨
}

라벨과 함께 특정 값 반환하기

return@lit 1 // 라벨 lit에 해당하는 블록에서 1을 반환

암묵적 라벨

fun retFunc(){
  println("start of retFunc")
  inlineLambda(13,3) { a,b -> // 1. 라벨 지정을 하지 않았음
    val result = a + b
    if(result > 10) return@inlineLambda  // 2. 람다함수의 이름을 이용한 암묵적 라벨
    println("result: $result")
  }
  println("end of retFunc") // 3. 이부분이 실행됨
}

익명 함수를 사용한 반환

fun retFunc(){
  println("start of retFunc")
  
  inlineLambda(13,3, fun(a,b){ // 익명 함수를 사용함. 익명함수는 비지역반환이 일어나지 않으므로 라벨을 사용하지 않아도 됨
    val result = a + b
    if(result > 10) return
    println("result: $result")
  }) //inlineLambda()함수의 끝
  
  println("end of retFunc") // 이 문장이 실행됨.  
}

람다식과 익명함수를 사용하기

// 람다식 방법

val getMessage = lambda@{ num:Int ->
  if(num !in 1..100){
    return@lambda "ERROR" // 레이블을 통한 반환
  }
  "SUCCESS" //마지막 식이 반환
}


//익명 함수 방법

val getMessage = fun(num: Int):String{
  if(num !in 1..100){
    return "ERROR"
  } 
  return "SUCCESS"
}
  1. break

반복문 탈출

fun labelBreak(){
  println("labelBreak")
  first@ for(i in 1..5){
    second@ for(j in 1..5){
      if (j == 3) break@first // 라벨을 이용하여 바깥 for문을 탈출할 수 있음
      println("i:$i,j:$j")
    }
    println("after for j")  //이 문장은 실행이 안됨
  }
}
  1. continue

반복문의 다음 조건문으로 이동

예외처리문

try{ 
  //  예외 발생 가능성이 있는 문장
  
  //  예외가 발생한 뒤의 문장은 실행되지 않음
  
} catch(e : 예외처리 클래스 명){  
  //  예외를 처리하기 위한 문장
  println("$e.message") // 예외 메세지 출력
  e.printStackTrace() // 스택의 추적. 어디서 예외가 발생했는지 알 수 있다.
} finally{
  // 반드시 실행되어야 하는 문장. 예외 발생시에도 실행됨
}

예외 발생 시키기

throw Exception(message: String) // 에러 메세지와 함께 예외 발생