본문 바로가기
Do it 코틀린 프로그래밍

코틀린 흐름 중단과 변환

by 차누감 2020. 5. 23.
흐름 제어문
return : 함수의 결과값을 반환하거나 지정된 라벨로 이동한다.
break : 반복문을 끝낸다.
continue : 반복문을 모두 수행하지 않고 다시 조건식으로 넘어간다.

예외 처리문
try{ ... } catch{ ... } : try 블록의 본문을 수행하는 도중 예외가 발생하면 catch 블록의 본문을 실행한다.
try{ ... } catch{ ... } finally{ ... } : 예외가 발생하여도 finally 블록 본문은 항상 실행한다. 

 

return으로 Unit 반환하기

Unit은 반환 값이 없는 경우 사용하는 자바의 void와 비슷합니다.

다만 코틀린에서는 Unit이란 반환하는 값이 아예 없는 뜻이 아니라 Unit이라는 자료형 자체를 반환합니다.

fun hello(name:String):Unit {   // Unit을 명시적으로 반환
    println(name)
    return Unit
}

fun hello2(name:String):Unit {   // Unit 생략한 반환
    println(name)
    return
}

fun hello3(name:String) {   // return문 자체를 생략
    println(name)
}

 

람다식에 retrun 사용하기

인라인(inline)으로 선언되지 않은 람다식에서는 return을 그냥 사용할 수 없습니다.

return@ label과 같이 라벨(label) 표기와 함께 사용해야 합니다.

 

☞라벨이란 코드 특정 위치를 임의로 표시한 것으로, @ 기호와 이름을 붙여 사용합니다.

인라인(inline)란 함수가 호출된 곳에 함수 본문을 복사해 넣어 함수의 분기 처리 없이 처리합니다.

(일반 함수 호출 시, 함수 본문으로 이동했다가 다시 함수 호출 후 부분으로 돌아오는 반면,

인라인 함수는 함수 내용을 호출 부분에 복사를 함으로 호출한 곳에서 다른 곳으로 이동하지 않습니다.)

 

fun main() {
    retFunc()	// (1)
}// main()..

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

fun retFunc(){
    println("start of retFunc")	// (2)
    inlineLambda(13,3){ a,b-> 	// (3)
    	val result =a+b;	
        if(result>10) return	// (4) 10보다 크면 retFunc()함수를 빠져나감.
        println("result : $result")
    }
    println("end of retFunc")
}

 <실행 결과>
 start of retFunc

 

람다식에서 라벨과 함께 return 사용하기

람다식에서 라벨을 정의해 return을 사용해야 합니다.

람다식 함수 이름 라벨 이름@{
   return@라벨 이름    //return @라벨 이름  <<오류.. 띄어쓰기 주의! 
}

 

fun main() {
    retFunc()	// (1)
}// main()..

fun inlineLambda(a:Int, b:Int, out: (Int, Int)-> Unit){		// line 제거 <변경된 곳>
    out(a,b)
}

fun retFunc(){
    println("start of retFunc")	// (2)
    inlineLambda(13,3) lit@ { a,b-> 	// (3)				// 라벨 사용 <변경된 곳>
    	val result =a+b;	
        if(result>10) return@lit	// (4) 				// 라벨 사용 <변경된 곳>
        println("result : $result")
    }
    println("end of retFunc")
}

 <실행 결과>
 start of retFunc
 end of retFunc

 

암묵적 라벨

람다식 명칭을 그대로 라벨처럼 사용할 수 있습니다.

fun retFunc(){
    println("start of retFunc")	// (2)
    inlineLambda(13,3) { a,b-> 	// (3)			// 라벨 지움 <변경된 곳>
    	val result =a+b;	
        if(result>10) return@inlineLambda	// (4) 	// 라벨 사용 <변경된 곳>
        println("result : $result")
    }
    println("end of retFunc")
}

 

break와 continue에 라벨 함께 사용하기

 

fun main() {
    labelBreak()
}// main()..

fun labelBreak(){

    for(x in 1..3){         // 1..2..3
        println(x)
        for(y in 1..5){     // 12345
            print(y)
        }// for(y)
        println()
    }// for(x)
}

<실행 결과>
1
12345
2
12345
3
12345

break 사용하기

fun main() {
    labelBreak()
}// main()..

fun labelBreak(){

    for(x in 1..3){         // 1..2..3
        println(x)
        for(y in 1..5){     // 12345
            print(y)
            if(y==3) break;     // 변경된 곳 break 사용
        }// for(y)
        println()
    }// for(x)
}

<실행 결과>
1
123
2
123
3
123

break@라벨 사용하기

만약 for(y in 1..5) 부분에서 break를 한다면 해당 반복문을 나갑니다.

그러나 for(x in 1...3)를 나가고 싶다면?! 아래와 같이 라벨을 이용하여 break를 합니다.

fun main() {
    labelBreak()
}// main()..

fun labelBreak(){

    first@ for(x in 1..3){         // 1..2..3 // 변경된 곳 라벨 사용
        println(x)
        for(y in 1..5){     // 12345
            print(y)
            if(y==3) break@first     // 변경된 곳 break@라벨 사용
        }// for(y)
        println()
    }// for(x)
}

<실행 결과>
1
123

※ continue에도 동일하게 적용됩니다.

댓글