본 책에서 제어는 크게 3가지가 있다.
조건문, 반복문, 흐름의 중단과 반환
조건문
코틀린은 조건문이 다른언어들에 비해서 간략하게 사용할 수 있는 표현들이 많다.
그래서 기존 습관을 버리고 간략화된 표현을 쓰도록 노력해야한다.
예를 들어 최댓값을 구하는 식을 한줄로 표현할 수 있는데, 한줄이다보니 가독성도 좋고 간단해 보인다.
val max = if (a > b) a else b
if절이 길어진 경우에도 한번 보자.
package chap04.section1
fun main() {
val a = 12
val b = 7
val max = if (a > b){
println("a 선택")
a
}
else{
println("b 선택")
b
}
println(max)
}
if와 else절 안에 a, b 딸랑 하나만 나오는 경우가 있어서 신기했다. (못알아볼뻔했다.)
in
조건중에 80 이상 89.9 이하를 아래와 같이 표현할 수 있다.
변수이름 in 시작값..마지막값 으로 나타낼 수 있다.
아래를 참고하자.
if(score >= 90){
grade = 'A'
} else if (score in 80.0..89.9) {
grade = 'B'
} else if (score in 70.0..79.9){
grade = 'C'
}
when
언뜻봐서는 C언어의 switch와 느낌이 비슷하다.
package chap04.section1
fun main() {
print("Enter the score: ")
val score = readLine()!!.toDouble()
var grade: Char = 'F'
when (score){
in 90.0..100.0 -> grade = 'A'
in 80.0..89.9 -> grade = 'B'
in 70.0..79.9 -> grade = 'C'
!in 70.0..100.0->grade = 'F'
}
println("Score: $score, Grade: $grade")
}
IntelliJ에서 in 구문을 작성하면 부등호가 표시된다. 너무 신기하다.
Any를 통해서도 when문을 사용할 수 있다.
package chap04.section1
fun main() {
cases("Hello")
cases(1)
cases(System.currentTimeMillis())
}
fun cases(obj: Any){
when(obj){
1 -> println("Int: $obj")
"Hello" -> println("String: $obj")
is Long -> println("Long: $obj")
!is String -> println("Not a String")
else -> println("Unknown")
}
}
반복문
반복문도 간단해보인다. in과 .. 조건문에서 범위로 봤던것이다.
for (x in 1..5) {
print(x)
}
파이썬과 비슷한 형태도 있다.
// kotlin
for (i in 1..5 step 2) print(i)
# python
for i in range(1, 5, 2):
print(i)
5부터 1까지 떨어뜨리고 싶을때는 downTo 키워드를 사용한다.
for (i in 5 downTo 1) print(i)
히스토그램을 한번 찍어보자
package chap04.section2
fun main() {
print("Enter the lines: ")
val n = readLine()!!.toInt()
for (line in 1..n){
for (space in 1..(n - line)) print(" ")
for (star in 1..(2 * line - 1)) print("*")
println()
}
}
while문과 do while문은 기존과 비슷하니 넘어가겠다.
흐름의 중단과 반환
inline을 사용한 람다식의 반환이 있다.
inline으로 선언되지 않은 람다식에서 return을 그냥 사용할 수 없고, return@label과 같이 라벨을 표기해야한다.
인라인으로 선언된 함수에서 람다식을 매개변수로 사용하면 람다식에서 return을 사용할 수 있다.
아래 코드는 label이 없기에 바로 retFunc를 탈출한다.
package chap04.section3
fun main() {
retFunc()
}
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
println("result: $result")
}
println("end of retFunc")
}
라벨을 쓰는 경우를 한번 살펴보자
package chap04.section3.noinline
fun main() {
retFunc()
}
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 -> // 람다식 블록의 시작 부분에 라벨을 지정
val result = a + b
if(result > 10) return@lit // 라벨을 사용한 블록의 끝부분으로 반환
println("result: $result")
} // 이 부분으로 빠져나감
println("end of retFunc") // 이 부분이 실행
}
label을 사용하는 경우 잘 빠져나가는 것을 볼 수 있다.
try catch도 사용해보자.
아래 예시는 0으로 나누는 경우이다.
package chap04.section3
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 블록은 반드시 항상 실행됨")
}
}
throw를 통해 예외를 발생시킬 수 있다.
package chap04.section3
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이하입니다.")
}
사용자 정의 예외를 직접 만들 수도 있다.
아래 코드는 InvalidNameException이라는 클래스를 직접 선언한 경우이다.
package chap04.section3
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.")
}
}
6주차 - 프로퍼티와 초기화 (3) | 2024.01.09 |
---|---|
5주차 - 클래스와 객체의 정의 (1) | 2024.01.06 |
3주차 - 함수와 함수형 프로그래밍 (0) | 2024.01.02 |
2일차 - 패키지, 변수와 자료형, 연산자 (1) | 2023.12.26 |
1일차 - 코틀린 시작하기 (1) | 2023.12.22 |
댓글 영역