코틀린 Conditions and loops

if expression(식)

코틀린에서 if는 expression(식)입니다.(값을 반환하는) 그러므로 삼항 연산자가 존재하지 않습니다. if만으로 그 역할을 충분히 대체할 수 있습니다.

var max = a
if (a < b) max = b

// With else
var max: Int
if (a > b) {
    max = a
} else {
    max = b
}

// As expression
val max = if (a > b) a else b

if 식은 {}블럭을 가질 수 있고, 블럭의 마지막 줄은 식의 값이 됩니다.

fun main() {
    val a = 5
    val b = 3

    val max = if (a > b) {
    	print("Choose a: ")
        a // -> this is value
    } else {
    	print("Choose b: ")
        b // -> this is value
    }
    println(max)
}

[출력]
Choose a: 5

if를 식으로써 사용하여 값을 리턴하려고 하거나 변수에 대입하려고 할 때, else는 반드시 if와 함께 사용되어야 합니다.

When expression

when은 다양한 분기를 가질 수 있는 조건식입니다. C에서 파생된 언어들의 switch와 비슷한 역할을 합니다. 간단한 형태는 아래의 예제와 같습니다.

fun main() {
    val x = readLine()?.toInt()

    when (x) {
        1 -> print("x == 1")
        2 -> print("x == 2")
        else -> {
            print("x is neither 1 nor 2")
        }
    }
}

when은 조건식과 조건문 두 가지 형태로 사용될 수 있습니다. 조건식으로 사용되는 경우에 첫번째로 일치하는 분기의 값이 전체 조건식의 값이 됩니다. 조건문으로 사용되는 경우에는 개별 분기의 값이 무시됩니다.

else 분기는 다른 분기들이 충족시키지 못하는 조건들에 대해서 실행됩니다.

when이 조건식으로 사용되는 경우, else 분기는 필수로 포함되어야 합니다. 예외적으로 enum클래스와 sealed클래스처럼 컴파일러가 가능한 모든 조건을 확인할 수 있는 경우에는 else를 사용하지 않을 수 있습니다.

import java.util.Random

enum class Bit {
    ZERO, ONE
}

fun getRandomBit(): Bit {
    val rand = Random().nextInt() // generate random int

    return if (rand % 2 == 0) Bit.ZERO else Bit.ONE
}

fun main() {
    val numericValue = when (getRandomBit()) {
        Bit.ZERO -> 0
        Bit.ONE -> 1
        // 'else' is not required because all cases are covered
    }
    println(numericValue)
}

when 조건문에서 Boolean, enum, sealed, nullable 타입이 있고 가능한 모든 경우의 수에 대해 분기가 존재하지 않는다면 else 분기는 반드시 존재해야 합니다.

import java.util.Random

enum class Color {
    RED, GREEN, BLUE
}


fun getRandomColor(): Color {
    val rand = Random().nextInt()
    val ret =
        if (rand % 3 == 0) Color.RED
        else if (rand % 3 == 1) Color.GREEN
        else Color.BLUE

    return ret
}

fun main() {
    when (getRandomColor()) {
        Color.RED -> println("red")
        Color.GREEN -> println("green")
        Color.BLUE -> println("blue")
        // 'else' is not required because all cases are covered
    }

    when (getRandomColor()) {
        Color.RED -> println("red") // no branches for GREEN and BLUE
        else -> println("not red") // 'else' is required
    }
}

여러 케이스를 하나의 분기에서 처리할 수도 있습니다.

when (x) {
	0, 1 -> println(zero or one)
    else -> println(not zero or one)
}

임의의 식을 분기 조건으로 사용할 수도 있습니다.

when (x) {
    s.toInt() -> print("s encodes x")
    else -> print("s does not encode x")
}

in 또는 !in을 사용해서 콜렉션 안에 있는 값을 검사하거나 범위의 값을 확인할 수도 있습니다.

fun main() {
    val x = readLine()?.toInt()

    val validNumbers = arrayListOf(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
    when (x) {
        in 1..10 -> print("x is in the range")
        in validNumbers -> print("x is valid")
        !in 10..20 -> print("x is outside the range")
        else -> print("none of the above")
    }
}

is와 !is를 사용하여 값이 특정 타입인지를 확인할 수도 있습니다. is로 타입체크를 하면 스마트 캐스트가 발생하여 별도의 작업 없이 is-check를 진행한 타입의 메소드와 프로퍼티를 사용할 수 있습니다.

fun hasPrefix(x: Any) = when(x) {
    is String -> x.startsWith("prefix")
    else -> false
}

when은 if-else if 체인의 대체물로 사용될 수도 있습니다. 인수가 제공되지 않으면 분기 조건은 단순히 부울 표현식이며 조건이 참일 때 분기가 실행됩니다.

when {
    x.isOdd() -> print("x is odd")
    y.isEven() -> print("y is even")
    else -> print("x+y is odd")
}

For loop

for 반복문은 이터레이터가 존재하는 모든 요소를 반복합니다.
이 말은 for반복문이 사용되는 객체에 Iterator<>를 반환하는 iterator() 멤버 함수 또는 확장 함수가 있어야 함을 의미합니다.
또한 next()와 hasNext() 멤버함수 또는 확장함수도 반드시 필요합니다.
이 세가지 함수는 모두 operator로 선언되어야 합니다.

for (item in collection)
	print(item)
    
for (item in collection) {
	print(item)
} // The body of for can be a block.

range식을 사용하여 숫자 범위를 반복할 수 있습니다.

for (i in 1..10)
	print(i) // 출력: 12345678910

for (i in 6 downTo 0 step 2) {
    print(i) // 출력: 6420
}

indices를 사용하면 배열이나 리스트에 대해 인덱스를 사용하여 반복할 수 있습니다.

fun main() {
    val intArr = intArrayOf(1, 2, 3)
    for (i in intArr.indices) {
        print(i) // 출력: 012
    }
}

withIndex를 사용하면 배열이나 리스트에 대해 인덱스와 값 모두 사용하여 반복할 수도 있습니다.

fun main() {
    val intArr = intArrayOf(1, 2, 3)
    for ((value, index) in intArr.withIndex()) {
        println("($value, $index)")
    }
}

[출력]
(0, 1)
(1, 2)
(2, 3)

좋은 웹페이지 즐겨찾기