흐름 제어
return : 함수에서 결괏값을 반환하거나 지정된 라벨로 이동
break : for나 while의 조건식에 상관없이 반복문을 끝냄
continue : for나 while의 반복문의 본문을 모두 수행하지 않고 다시 조건으로 넘어감
예외 처리문
- try {...} catch {...} : try 블록의 본문을 수행하는 도중 예외가 발생하면 catch 블록의 본문을 실행
- try {...} catch {...} finally {...} : 예외가 발생해도 finally 블록 본문은 항상 실행
return으로 값 반환하기
fun add ( a : Int, b : Int ) : Int {
return a + b
println( "이 코드는 실행되지 않습니다." ) // 여기에 도달하지 않음
}
return으로 Unit 반환하기
// 1. Unit을 명시적으로 반환
fun hello(name : String) : Unit {
println( name )
return Unit
}
// 2. Unit 이름을 생략한 반환
fun hello (name : String) : Unit {
println( name )
return
}
// 3. return문 자체를 생략
fun hello (name : String) {
println( name )
}
람다식에서 return 사용하기 - InlineLambdaReturn.kt
fun main() {
retFunc()
}
inline fun inlineLambda ( a : Int, b : Int, out : (Int, Int) -> Unit ) {
out ( a, b )
}
fun retFunc() {
println("start of retFunc") // 1
inlineLambda(13, 3) { a, b -> // 2
val result = a + b
if ( result > 10 ) return // 3. 10보다 크면 이 함수를 빠져 나감 (4,5 실행안함)
println("result : $result") // 4. 10보다 크면 이 문장에 도달하지 못함
}
println("end of retFunc") // 5
}
람다식에서 라벨 사용
람다식 함수명 라벨이름@ {
...
return@라벨이름
}
fun inlineLambda(a : Int, b : Int, out : (Int, Int) -> Unit) { // inline이 제거됨
out(a, b)
}
fun retFunc() {
println("start of retFunc")
inlineLambda(13, 3) lit@{ a, b -> // 1. 람다식 블록의 시작 부분에 라벨을 지정함
val result = a + b
if ( result > 10 ) return@lit // 2. 라벨을 사용한 블록의 끝부분으로 반환
println ( "result : $result" )
} // 3
println("end of retFunc") // 4. 이 부분이 실행됨
}
익명 함수의 사용
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") // return 되도 실행됨!!
}
람다식과 익명 함수 사용
- 람다식 방법
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"
}
val result = getMessage(99)
break와 continue
- for나 while, do...while문 루프를 빠져 나옴
for (반복 조건) {
// 본문
...
if ( 중단 조건 ) {
break // for문 빠져나감 본문2 하지 않음
}
// 본문
}
for (반복 조건) {
// 본문1
...
if ( 중단 조건 ) {
continue // 본문2를 하지 않고 다시 for문으로!
}
// 본문2
}
NormalBreakContinue.kt
fun main() {
for ( i in 1..5) {
if ( i == 3 ) break
print ( i )
}
println() // 개행 문자
println( "outside" )
}
라벨 없는 break와 라벨을 사용한 break
fun labelBreak() {
println( "labelBreak" )
for ( i in 1..5) {
second@ for ( j in 1..5) {
if ( j == 3) break // second@ 빠져나감!
println( "i : $i, j : $j" )
}
println( "after for j" )
}
println( "after for i" )
}
fun labelBreak() {
println( "labelBreak" )
first@ for ( i in 1..5) {
second@ for ( j in 1..5) {
if ( j == 3) break@first
println( "i : $i, j : $j" )
}
println( "after for j" )
}
println( "after for i" )
}
예외(exception)
- 실행 도중의 잠재적인 오류까지 검사할 수 없기 때문에 정상적으로 실행이 되다가 비정상적으로 프로그램이 종료되는 경우
- 운영체제의 문제 (잘못된 시스템 호출의 문제)
- 입력값의 문제 (존재하지 않는 파일 혹은, 숫자 입력란에 문자 입력 등)
- 받아들일 수 없는 연산 (0으로 나누기 등)
- 메모리의 할당 실패 및 부족
- 컴퓨터 기계 자체의 문제 (전원 문제, 망가진 기억 장치 등)
예외를 대비하기 위한 구문
try {
예외 발생 가능성 있는 문장
} catch ( e : 예외처리 클래스명 ) {
예외를 처리하기 위한 문장
} finally {
반드시 실행되어야 하는 문장
}
- 반드시 실행해야 할 작업이 없다면 finally 블록은 생략하고 try~catch 블록만으로 코드를 구성할 수 있다.
TryCatch.kt
fun main() {
val a = 6
val b = 0
val c : Int
try {
c = a/b // 0으로 나눔
} catch ( e : Exception ) {
println ( "Exception is handled." )
} finally {
println ( "finally 블록은 반드시 항상 실행됨" )
}
}
Exception is handled.
finally 블록은 반드시 항상 실행됨
특정 예외 처리
- 산술 연산에 대한 에외를 따로 특정해서 잡을 때
} catch ( e : ArithmeticException) {
println ( "Exception is handled. ${ e.message}" )
}
Exception is handled. / by zero
finally 블록은 반드시 항상 실행됨
- 스택의 추적
} catch ( e : Exception) {
e.printStackTrace()
}
finally 블록은 반드시 항상 실행됨
java.lang.ArithmeticException : / by zero
at com.acaroom.kotlin.chap04.section3.TryCatchKt.main(TryCatch.kt : 9)
- 특정 조건에 따른 예외 발생
throw Exception(message : String)
ThrowExceptionTest.kt
fun main() {
var amount = 600
try {
amount -= 100
checkAmount ( amount )
} catch ( e : Exception ) {
println ( e.message )
}
println( "amount : $amount" )
}
fun checkAmount ( amount : Int ) {
if ( amount < 1000 )
throw Exception( "잔고가 $amount 으로 1000 이하입니다." )
}
사용자 예외 정의
class <사용자 예외 클래스명> (message : String) : Exception( message )
class InvalidNameException (message : String) : Exception(message) // 1. 사용자 예외 클래스
fun main() {
var name = "Kildong123" // 2. 숫자가 포함된 이름
try {
validateName( name )
} catch ( e : InvalidNameException ) { // 4. 숫자가 포함된 예외 처리
println( e.message )
} catch ( e : Exception ) { // 5. 기타 예외 처리
println( e.message )
}
}
fun validateName ( name : String ) {
if (name.matches (Regex(".*\\d+.*"))) { // 3. 이름에 숫자가 포함되어 있으면 예외 던지기
throw InvalidNameException ( "Your name : $name : contains numerals." )
}
}
'# 02 > 코틀린' 카테고리의 다른 글
[Kotlin] 생성자 (0) | 2019.08.06 |
---|---|
[Kotlin] 클래스와 객체의 정의 (0) | 2019.08.06 |
[Kotlin] 반복문 (0) | 2019.07.18 |
[Kotlin] MVP Model 구성 (0) | 2019.07.15 |
[Kotlin] MVP 패턴 소개 2 (0) | 2019.07.15 |