개발/코틀린

(코틀린) 조건문, 반복문

DinoDev 2022. 9. 25. 15:39
728x90
반응형

조건문

조건 값에 따라 동작을 수행하지 않을 수도 있고 여러 가지 동작중 하나의 동작을 수행할 수 있습니다.

if

if를 사용하면 Boolean 값에 따라서 동작을 다르게 수행할 수 있습니다.

// if를 사용해서 조건에 따른 값을 다르게 전달할 수 있습니다.
fun max(a: Int, b: Int): Int {
    return if (a > b) a else b
}

{}를 사용해서 여러 줄의 동작을 수행할 수 있습니다.

// 반환값이 있는 if는 else가 필수로 구현되어야 합니다.
fun max(a: Int, b: Int): Int {
    return if (a > b) {
        println("최대값은 a")
        a
    } else {
        println("최대값은 b")
        b
    }
}

반환 값이 없는 형태의 if문을 작성할 수 있습니다.

fun max(a: Int, b: Int) {
    if (a > b) {
        println("최대값은 a")
    } else {
        println("최대값은 b")
    }
}

else if를 추가해서 조건을 추가 할 수 있습니다.

fun max(a: Int, b: Int) {
    if (a > b) {
        println("최대값은 a")
    } else if (b > a) {
        println("최대값은 b")
    } else {
        println("a와 b는 같습니다.")
    }
}

범위, 진행, 연산

순서가 정해진 값 사이의 수열을 표현하는 몇 가지 타입을 제공합니다.

range를 표현할 때는 .. 연산자를 사용합니다.

val chars = 'a'..'z'
val towDigits = 10..99
val zero2One = 0.0..1.0

in과 !in을 사용해서 포함되어있거나 포함되어있지 않거나를 표현할 수 있습니다.

fun main() {
    println(55 in towDigits) // true
    println(55 !in towDigits) // false
}

until을 사용하면 마지막 숫자는 포함하지 않는 range가 생성됩니다.

val range1 = 1..10 // 1과 10을 포함한 범위
val range2 = 1 until 10 // 10을 포함하지 않는 범위

..나 until은 작은 수에서 큰 수를 만들 때 사용합니다.

큰 수에서 작은 수를 만들 때 downTo를 사용합니다.

println(5 in 10 downTo 1) // true
println(5 in 1 downTo 10) // false

step을 사용하면 range를 만들 때 간격을 지정할 수 있습니다.

1..10 step 3 // 1, 4, 7, 10
15 downTo 9 step 2 // 15, 13, 11, 9

when

if를 사용하면 여러 조건을 추가해서 사용할 수 있지만 코틀린에서 when을 사용해서 더욱더 간결하게 표현할 수 있습니다.

// if
fun hexDigit(n: Int): Char {
    return if (n in 0..9) {
        '0' + n
    } else if (n in 10..15) {
        'A' + n - 10
    } else {
        '?'
    }
}

// when
fun hexDigit(n: Int): Char {
    return when {
        n in 0..9 -> {
            '0' + n
        }
        n in 10..15 -> {
            'A' + n - 10
        }
        else -> {
            '?'
        }
    }
}

// when: n 변수만 확인
fun hexDigit(n: Int): Char {
    return when (n) {
        in 0..9 -> {
            '0' + n
        }
        in 10..15 -> {
            'A' + n - 10
        }
        else -> {
            '?'
        }
    }
}

반복문

같은 동작을 반복해서 수행하는 for, while, do-while을 제공합니다.

for

for는 배열이나 리스트 같은 collection을 순회하기 위해서 많이 사용합니다.

fun main() {
    val a = IntArray(10) { it }
    var sum = 0

    for (x in a) {
        sum += x
    }
    println("Sum: $sum")
}

while

while은 조건을 먼저 검사해서 반복할 지 말지 결정합니다.

import kotlin.random.Random

fun main() {
    val num = Random.nextInt(1, 101)
    var guess = 0

    while (guess != num) {
        guess = readLine()!!.toInt()
        if (guess < num) {
            println("Too small")
        } else if (guess > num) {
            println("Too big")
        }
    }
    println("Right: it's $num")
}

do-while

do-while은 조건을 먼저 검사하지 않고 동작을 수행한 후에 조건을 검사해서 반복할지 말지 결정합니다.

fun main() {
    var sum = 0
    var num: Int

    do {
        num = readLine()!!.toInt()
        sum += num
    } while (num != 0)

    println("Sum: $sum")
}

break, continue

루프의 흐름을 제어하기 위해서 break와 continue를 사용합니다.

break는 루프를 종료하고 탈출하기 위해 사용하고, continue는 현재 루프의 동작을 더 이상 수행하지 않고 다음 루프를 동작합니다.

import kotlin.random.Random

fun main() {
    val num = Random.nextInt(1, 101)

    while (true) {
        val guess = readLine()!!.toInt()
        val message = when {
            guess !in 1 until 101 -> {
                println("Out of range")
                continue
            }
            guess < num -> "Too small"
            guess > num -> "Too big"
            else -> break
        }
        println(message)
    }
    println("Right: it's $num")
}

label

break, continue는 다중 루프에서는 내부에 있는 루프만 탈출이 가능합니다.

반복분 키워드 앞에 label@를 붙이고 continue@label, break@label 처럼 사용합니다.

fun indexOf(mainArray: IntArray, subArray: IntArray): Int {
    outerLoop@ for (i in mainArray.indices) {
        for (j in subArray.indices) {
            if (mainArray[i + j] != subArray[j]) {
                continue@outerLoop
            }
        }
        return i
    }
}

tailrec

꼬리 재귀인 trailrec은 컴파일 최적화를 지원합니다.

tailrec fun binIndexOf(
    x: Int,
    array: IntArray,
    from: Int = 0,
    to: Int = array.size,
): Int {
    if (from == to) return -1

    val midIndex = (from + to - 1) / 2
    val mid = array[midIndex]

    return when {
        mid < x -> binIndexOf(x, array, midIndex + 1, to)
        mid > x -> binIndexOf(x, array, from, midIndex)
        else -> midIndex
    }
}

decompile의 결과

public static final int binIndexOf(int x, @NotNull int[] array, int from, int to) {
   while(true) {
      Intrinsics.checkNotNullParameter(array, "array");
      if (from == to) {
         return -1;
      }
      int midIndex = (from + to - 1) / 2;
      int mid = array[midIndex];
      if (mid < x) {
         from = midIndex + 1;
      } else {
         if (mid <= x) {
            return midIndex;
         }
         to = midIndex;
      }
   }
}
728x90
반응형

'개발 > 코틀린' 카테고리의 다른 글

(코틀린) 클래스  (0) 2022.10.03
(코틀린) 예외처리  (0) 2022.09.25
(코틀린) 함수  (0) 2022.09.24
(코틀린) 코틀린 기초  (0) 2022.09.18
(코틀린) 코틀린 시작하기 2 - IntelliJ로 코틀린 프로젝트 만들기  (0) 2022.09.01