https://kotlinlang.org/docs/control-flow.html
Conditions and loops
If expression
코틀린에서는 if는 표현식이다.(값을 반환할 수 있다.)
그렇기에 코틀린에서는 삼항 연산자(condition ? then : else)가 없다.
If가 이 역할을 하기 때문이다.
fun main(){
val a = 1
val b = 2
var max = 0
max = if (a > b) a else b
val maxOr100 = if (a > 100) a else if(b > 100) b else 100
}
When expression
When은 다양한 곳을 분기할 수 있는 조건식을 정의한다.
C언어에서의 switch라고 생각하면 된다.
fun main(){
val x = 0
when(x){
0 -> println("x is 0")
1 -> println("x is 1")
2 -> println("x is 2")
else -> println("x is neither 1 nor 2")
}
}
When은 만족하는 condition이 있을 때까지 순서대로 매칭해 간다.
else는 아무것에도 해당하지 않을 때를 정의한다.
만약 When이 표현식으로 사용된다면 Else branch는 필수적이다.
그래도 컴파일러가 모든 경우의 수를 커버하고 있다고 알 수 있으면, Else는 생략 가능하다.
enum class Bit{
ZERO, ONE
}
fun main(){
val a = Bit.ZERO
when(a){
Bit.ZERO -> println("Bit.ONE")
Bit.ONE -> println("Bit.TWO")
}
}
값이 범위 안에 속하는지도 확인할 수 있다.
fun main(){
val a = 5
when(a){
in 1..10 -> println(a)
else -> println("else")
}
}
여기서도 is로 타입을 검사하면 스마트캐스팅이 되어 추가적으로 검사할 필요가 없다.
fun hasPrefix(x: Any) = when(x) {
is String -> x.startsWith("prefix")
else -> false
}
For loops
for는 iterator를 순환합니다.
for (item in collection) print(item)
숫자를 반복하고 싶다면, range expression을 사용한다.
for (i in 1..3) {
println(i)
}
for (i in 6 downTo 0 step 2) {
println(i)
}
While loops
while과 do-while은 조건이 만족할 때까지 계속 ㅁ반복한다.
while: 조건을 체크하고 그것이 참이면 실행한다. 이것을 반복한다.
do-while: 일단 블록을 실행하고 조건을 체크한다.
while (x > 0) {
x--
}
do {
val y = myFunc()
} while (y != null) // y is visible here!
Returns and jumps
Returns and jumps
fun main(){
val a:Int? = null
val b = (a ?: return).toString()
println(b)
}
return은 본인이 속한 가장 가까운 함수를 리턴한다
break은 본인이 속한 가장 가까운 loop를 정지한다.
continue는 루프의 다음 스텝으로 넘어간다.
Break and continue labels
fun main(){
loop@ for (i in 1..10) {
for (j in 1..10) {
if(i != j) break@loop
println("$i $j")
}
}
}
코틀린에서는 표현식에 label을 붙일 수 있다.
라벨은 @로 끝나며, abc@와 같은 형태가 된다.
break와 continue를 사용하여 해당 부분으로 jump 할 수 있다.
Return to labels
fun main(){
listOf(1, 2, 3, 4, 5).forEach lit@{
if (it == 3) return@main
print(it)
}
print(" done with explicit label")
}
이렇게 return에서도 라벨을 사용하여 리턴할 수 있다.
Exceptions
예외 처리는 크게 2가지로 나뉜다.
Throwing exceptions: 문제가 발생 했을 때 알린다.
Catching exceptions: 문제가 발생 했을 때 어떤 식으로 처리할 것인지 다룬다.
이런 예외 처리는 코드를 더 예측가능하게 도와줄 수 있다.
Throw exceptions
throw IllegalArgumentException()
throw 키워드를 사용하여 Exception을 발생시킨다.
Exception이 발생하는 것은 런타임 중에 예상하지 못한 문제가 발생했다는 것을 알리는 것이다.
Throw Exceptions with precondition functions
코틀린은 조건을 체크하고 에러를 발생시켜주는 precondition function이 존재한다.
Precondition function | Use case | Exception thrown |
require() | 유저의 input이 valid 한지 확인 | IllegalArgumentException |
check() | Object 혹은 변수의 상태가 valid 한지 확인 | IllegalStateException |
error() | 잘못된 상태나 조건을 알린다. | IllegalStateException |
- require() function
fun getIndices(count: Int): List<Int> {
require(count >= 0) { "Count must be non-negative. You set count to $count." }
return List(count) { it + 1 }
}
- check() function
fun main() {
var someState: String? = null
fun getStateValue(): String {
val state = checkNotNull(someState) { "State must be set beforehand!" }
check(state.isNotEmpty()) { "State must be non-empty!" }
return state
}
// If you uncomment the line below then the program fails with IllegalStateException
// getStateValue()
someState = ""
// If you uncomment the line below then the program fails with IllegalStateException
// getStateValue()
someState = "non-empty-state"
// This prints "non-empty-state"
println(getStateValue())
}
check에서 condition이 false라면 exception을 throw한다.
- error() function
class User(val name: String, val role: String)
fun processUserRole(user: User) {
when (user.role) {
"admin" -> println("${user.name} is an admin.")
"editor" -> println("${user.name} is an editor.")
"viewer" -> println("${user.name} is a viewer.")
else -> error("Undefined role: ${user.role}")
}
}
fun main() {
// This works as expected
val user1 = User("Alice", "admin")
processUserRole(user1)
// Alice is an admin.
// This throws an IllegalStateException
val user2 = User("Bob", "guest")
processUserRole(user2)
}
그냥 exception을 발생시켜버린다.
Handle exceptions using try-catch blocks
exception이 발생하면, 그래도 프로그램을 이어가기 위해 exception을 handling 해야 한다.
그럴 때 try-catch를 사용한다.
try {
// exception을 발생시키는 코드
} catch (e: YourException) {
// exception을 handling 하는 코드
}
또한 if와 마찬가지로 try-catch는 expression으로 사용 할 수 있다.
fun main() {
val num: Int = try {
10/0
} catch (e: ArithmeticException) {
-1
}
println("Result: $num")
}
또, 하나의 try에 대하여 여러개의 Catch를 작성 할 수 있다.
The finally block
finally block은 무조건 실행되는 부븐이다.
이 finally block은 try에서 exception이 발생하더라도 무조건 실행된다.
그렇기에 finally는 네트워크나 파일과 같은 리소스를 Close 하는 것에서 중요하다.
try {
// Exception이 발생 할 수 있는 코드
}
catch (e: YourException) {
// Exception을 handling 하는 코드
}
finally {
// 무조건 실행되어야 하는 코드
}
이 finally 블록은 catch 블록을 작성하지 않아도 작성할 수 있다.
'백엔드 > 코틀린' 카테고리의 다른 글
Idioms (1) | 2024.10.01 |
---|---|
Basic syntax (0) | 2024.09.28 |
코틀린 시작 (0) | 2024.09.28 |