모든 내용은 Do it! 코틀린 프로그래밍을 바탕으로 정리한 것입니다.
조건문
if 문과 if~else 문
if (조건식) {
수행할 문장 // 조건식이 true인 경우에만 실행
...
}
if (조건식) {
수행할 문장 // 조건식이 true인 경우
} else {
수행할 문장 // 조건식이 false인 경우
}
- 수행할 문장이 하나인 경우, 블록 구문인 중괄호 생략 가능
- 조건문을 한 줄에 구성할 때, 조건식에 따라 값을 할당하도록 변수 이름 단독으로 쓸 수 있음
- 블록의 표현식이 길어질 때, 람다식처럼 블록의 마지막 표현식이 변수에 반환되어 할당됨
else if 문 ; 조건문 중첩
val number = 0
val result = if (number > 0)
"양수 값"
else if (number < 0)
"음수 값"
else
"0"
- 여러 조건을 적용하기 위해 else if를 사용하여 조건문을 중첩할 수 있음
- 필요한 만큼 조건을 조합할 수 있지만, 너무 많으면 코드 읽기가 어려워짐
- 포함 여부 확인 : in 연산자와 2개의 점(..)으로 구성된 범위 연산자 제공
- 변수 이름 in 시작값..마지막값
- 시작값과 마지막값까지 포함하는 범위를 계산함
when 문 ; 다양한 조건 처리
> 인자를 사용하는 when 문
when (인자) {
인자에 일치하는 값 혹은 표현식 -> 수행할 문장
인자에 일치하는 범위 -> 수행할 문장
...
else -> 수행할 문장
}
- 화살표(->) 왼쪽 : 일치하는 값, 표현식, 범위로 조건을 나타냄
- 일치되는 조건을 한 번에 여러 개 표현하려면 쉼표(,) 사용 : 0, 1 -> print("x == 0 or x == 1")
- 함수의 반환값 사용 가능 : parseInt(s) -> print("일치함!")
- in 연산자와 범위 지정자 사용 가능 : !in 1..10 -> print("x는 1 이상 10 이하의 범위에 포함되지 않습니다.")
- is 키워드 사용 가능(특정 자료형 검사) : is String -> "문자열입니다."
- 화살표(->) 오른쪽 : 수행할 문장을 사용
- 문장이 여러 줄이라면 중괄호를 사용해 블록으로 구성할 수 있음
- 조건과 일치하는 값이 없으면 else문 다음에 작성한 문장을 실행
- switch~case 문과 비슷하지만 각 수행 문장을 멈추는 break와 같은 문장이 필요하지 않음
> 인자가 없는 when 문
when문에 인자가 주어지지 않으면 else if 문처럼 각각의 조건을 실행할 수 있음 (조건이나 표현식을 직접 만들 수 있기 때문)
fun main() {
print("Enter the score: ")
val score = readLine()!!.toDouble()
var grade: Char = 'F'
when {
score >= 90.0 -> grade = 'A'
score in 80.0..89.9 -> grade = 'B'
score in 70.0..79.9 -> grade = 'C'
score < 70.0 -> grade = 'F'
}
println("Score: $score, Grade: $grade")
}
→ 변수와 조건식을 when 문에 직접 사용함
> 다양한 자료형의 인자를 받는 when 문
fun main() {
cases("Hello") // 2
cases(1) // 1
cases(System.currentTimeMillis()) // 3
cases(MyClass()) // 4
}
fun cases(obj: Any) {
when(obj) {
1 -> println("Int: $obj") // 1
"Hello" -> println("String: $obj") // 2
is Long -> println("Long: $obj") // 3
!is String -> println("Not a String") // 4
else -> println("Unknown") // 5
}
}
- when 문의 인자로 Any를 사용하면 다양한 자료형의 인자를 받을 수 있음
- 숫자, 문자, 클래스의 객체
반복문
for 문
for (요소 변수 in 컬렉션 또는 범위) { 반복할 본문 }
- 자바의 for문 : 초기화식, 조건식, 증감식을 세미콜론(;)으로 구분
- 코틀린의 for문 : in 연산자를 함께 사용 (세미콜론 사용 불가)
- 역순 : downTo 키워드 사용 - for (i in 5 downTo 1) print(i)
- 증감식 : step 키워드 사용 - for (i in 1..5 step 2) print(i)
while 문
while (조건식) {
본문
...
}
- 조건식이 true를 만족하는 경우 while 문의 블록을 무한히 반복
- 조건식이 false가 되면 실행문이 중단되어 while 루프를 빠져 나감
- 조건식을 true로 해 무제한으로 반복할 수 있음
do-while 문
do {
본문
} while (조건식)
- do 블록에 작성한 본문을 한 번은 실행한 다음 마지막에 조건식을 검사해서 true가 나오면 작업을 반복
흐름의 중단과 반환
흐름 제어문 |
|
예외 처리문 |
|
return 문
- return 이후의 코드는 실행되지 않음
- Unit 반환 (Unit이라는 반환 값은 Unit이라는 자료형 자체를 반환하는 것 ≠ void)
- 명시적으로 Unit을 반환하는 경우
- Unit 이름을 생략한 반환 ( = 값 없이 return만 사용한 경우)
- return 문 자체를 생략한 경우
> 람다식에서 return 사용하기
inline 으로 선언되지 않은 람다식에서는 return을 사용할 수 없음 (이전 포스팅 참고)
→ return@label과 같이 라벨 표기와 함께 사용해야 함
* 라벨 : 코드에서 특정한 위치를 임의로 표시한 것, @ 기호와 이름을 붙여서 사용
- 인라인 함수에서의 return은 람다식 바깥의 retFunc()까지 빠져나가게 됨 : 비지역 반환
- 람다식에서 라벨을 정의하여 return을 사용 → 비지역 반환 방지
- 라벨 지정 - 라벨 이름@ / 사용 시 - return@라벨 이름
- 암묵적 라벨 : 람다식 명칭을 그대로 라벨처럼 사용
- 따로 정의하지 않고 사용 시 return@람다식명칭
> 익명 함수에서 return
라벨을 사용하지 않고도 가까운 익명 함수 자체가 반환되므로 라벨을 사용한 람다식과 동일한 결과를 가질 수 있음
fun retFunc() {
println("start of retFunc")
inlineLambda(13, 3) fun(a, b) {
val result = a+b
if (result > 10) return
println("result: $result")
}
println("end of retFunc")
}
보통의 경우에는 람다식을 사용하고 return과 같이 명시적으로 반환해야 할 것이 여러 개라면 익명 함수를 사용하는 것이 좋음
break 문과 continue 문
- break : 더 이상 반복을 수행하지 않고 해당 블록을 빠져나감
- continue : 조건식이 false가 되는 부분만 처리하지 않고 계속 반복문을 수행함
> 라벨 사용하기
라벨을 사용해서 반복문이 중단되는 위치를 바꿀 수 있음
→ continue도 마찬가지
- 일반적인 break 였을 경우 : j가 3인 경우만 제외한 모든 i의 경우의 수가 출력되었을 것
- first@ 라벨을 사용한 break : 라벨이 선언된 블록 전체를 break 하여 탈출함
예외 처리
예외(Exception) : 해당 코드가 제대로 작동하지 못하고 중단되는 현상
→ 실행 도중의 잠재적인 오류까지 검사할 수 없기 때문에 정상적으로 실행되다가 비정상적으로 프로그램이 종료될 수 있음
- 운영체제의 문제 (잘못된 시스템 호출의 문제)
- 입력값의 문제 (존재하지 않는 파일 또는 숫자 입력란에 문자 입력 등)
- 받아들일 수 없는 연산 (0으로 나누기 등)
- 메모리의 할당 실패 및 부족
- 컴퓨터 기계 자체의 문제 (전원 문제, 망가진 기억 장치 등)
이러한 예외를 대비하는 것 = 예외 처리
try {
예외 발생 가능성 있는 문장
} catch (e: 예외 처리 클래스 이름) {
예외를 처리하기 위한 문장
} finally {
반드시 실행되어야 하는 문장
}
- catch의 인자에 Exception 클래스는 일반적인 모든 예외를 가리킴
- 위의 코드처럼 산술 연산에 대한 예외를 따로 특정해서 잡으려면 ArithmeticException을 사용할 수 있음
- e.message : 객체 e의 멤버 변수 또는 프로퍼티로 불리는 message를 읽으면 예외 원인을 간단히 출력해 줌
- e.printStackTrace() : 스택의 추적
- 어떤 특정 예외가 발생했는지 알 수 있고, 오류가 발생한 코드의 줄을 확인할 수 있음
- 추적 가능한 이유 : 프로그램이 디버깅 정보를 유지하고 있기 때문
예외 발생 시키기
throw 키워드 : 의도적으로 예외를 발생할 수 있음
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 이하입니다.")
}
→ amount가 1000 이하일 때, throw로 예외를 발생시키고 이것은 main()의 catch가 잡아서 처리
* 공을 던지고 받는 캐치볼 놀이를 생각하면 이해하기 쉬움
사용자 정의 예외
기본 Exception 클래스로부터 새롭게 사용자가 정의한 예외 클래스를 만들 수 있음
class <사용자 예외 클래스 이름>(message: String) : Exception(message)
콜론(:)을 사용해 하위 클래스인 사용자 예외 클래스 이름을 지정해 예외로 만들 수 있음
class InvalidNameException(message: String) : Exception(message)
fun main() {
var name = "Kildong123"
try{
validateName(name)
} catch (e: InvalidNameException) {
println(e.message)
} catch (e: Exception) {
println(e.message)
}
}
fun validateName(name: String) {
if(name.matches(Regex(".*\\d+.*"))) // 이름에 숫자가 포함되어 있으면 예외발생
throw InvalidNameException("Your name: $name : contains numerals.")
}
'Kotlin > Kotlin 프로그래밍' 카테고리의 다른 글
[Kotlin] 다양한 클래스와 인터페이스 (1) (0) | 2021.04.21 |
---|---|
[Kotlin] 프로퍼티와 초기화 (0) | 2021.04.20 |
[Kotlin] 클래스와 객체 (2) (0) | 2021.04.19 |
[Kotlin] 클래스와 객체 (1) (0) | 2021.04.16 |
[Kotlin] 함수와 함수형 프로그래밍 (3) - 코틀린의 다양한 함수 (0) | 2021.04.13 |
[Kotlin] 함수와 함수형 프로그래밍 (2) - 고차함수와 람다식 (0) | 2021.04.07 |
[Kotlin] 함수와 함수형 프로그래밍 (1) (0) | 2021.04.02 |
[Kotlin] 변수와 자료형, 연산자 (2) (0) | 2021.04.02 |
댓글