Programming/Kotlin

코틀린(Kotlin) - enum, 제어문(if, when, while, for)

JunsuKim 2021. 9. 19.
728x90

enum

enum 키워드는 Enumerated Type으로 서로 연관된 상수 값들의 집합이다.

Java에서는 enum을 사용하지만 Kotlin에서는 enum class를 사용한다.

enum class Subject {
    MATH, KOREAN, ENGLISH, SCIENCE
}

여기서 enum은 혼자 사용할 수 없는 소프트 키워드이다. 또한 class 앞에 붙어야만 의미를 가지게 된다.

*class 앞에 붙지 않을 시 변수명으로 사용 가능하다.

enum의 장점

  • 인스턴스 생성을 안 해도 되어 값에 대한 안정성이 보장된다.
  • 코드가 간단해져 가독성이 좋다.

프로퍼티와 메서드가 있는 enum class 선언

enum에서도 class와 같이 프로퍼티, 메서드를 선언할 수 있다.

여기서 특이한 점은 Kotlin에서는 세미클론(;)을 사용하지 않지만 메서드를 선언할 시 세미클론(;)을 사용한다.

이는 프로퍼티와 메소드를 구별하기 위함이다.

enum class Color(val r: Int, val g: Int, val b: Int) {
    RED(255, 0, 0), ORANGE(255, 165, 0), YELLOW(255, 255, 0),
    BLUE(0, 0, 255), VIOLET(238, 130, 238);
    fun rgb() = (r * 256 + g) * 256 + b
}
println(Color.BLUE.rgb())

if

Java와 동일하게 사용되며 식으로 쓰인다.

var max = if(a > b) {
    println("a > b")
    a
}
else {
    println("a < b")
    b
}

when

Java의 switch과 유사하며 if와 마찬가지로 식으로 쓰인다.

fun getWarmth(color: Color) =
    when (color) {
        Color.RED ‐> "warm"
        Color.ORANGE ‐> "warm"
        Color.YELLOW ‐> "warm"
        Color.BLUE ‐> "cold"
        Color.VIOLET ‐> "cold"
    }

switch와는 다르게 default 대신 else를 사용하여 모든 분기 식에 만족하지 않을 때를 작성한다.

fun getWarmth(color: Color) =
    when (color) {
        Color.RED ‐> "very warm"
        Color.ORANGE, Color.YELLOW ‐> "warm"
        else ‐> "cold"
    }

when과 임의의 객체를 함께 사용

switch문은 분기 조건에 상수만을 사용할 수 있지만, when은 분기 조건에 임의의 객체를 허용한다.

fun mix(c1: Color, c2: Color) =
    when (setOf(c1, c2)) {
        setOf(RED, YELLOW) ‐> ORANGE
        setOf(YELLOW, BLUE) ‐> GREEN
        else ‐> throw Exception("Dirty color")
    }

*setOf() 함수는 인자로 전달받은 여러 객체를 포함하는 집합 Set 객체로 만드는 함수이다.

인자 없는 when 사용

위와 같이 임의의 객체를 함께 사용하는 when에서는 setOf함수를 사용하여 Set인스턴스를 계속 만들어낸다. 이로 인해 불필요한 객체들이 늘어난다. 이때 인자가 없는 when을 사용한다면, 불필요한 객체 생성을 줄일 수 있다. 

when에 인자가 없으려면, 각 분기의 조건이 Boolean 결과를 계산하는 식이어야 한다.

fun mixOpt(c1: Color, c2: Color) =
    when {
        c1 == RED && c2 == YELLOW ‐> ORANGE
        c1 == YELLOW && c2 == RED ‐> ORANGE
        c1 == YELLOW && c2 == BLUE ‐> GREEN
        else ‐> throw Exception("Dirty color")
    }

if, when의 블록

if, when의 각 분기에는 블록을 사용하는데, 블록 안의 마지막 줄이 if, when의 결과가 된다.

fun evalWithLogging(e: Expr): Int =
    when (e) {
        is Num -> {
            println("num : $ {e.value}")
            e.value // 결과
        }
        is Sum -> {
            val left = evalWithLogging(e.left)
            val right = evalWithLogging(e.right)
            println("sum : ${left} + ${right}
            left + right // 결과
        }
        else -> throw Exception("Unknown Exp")
    }

while

Kotlin에는 while문과 do~while문이 있고, 이들은 Java에서의 문법과 동일하다.

while(조건) {
    ....
}


do {
    ....
} while(조건)

범위와 수열

범위(Closed Range 인터페이스) : 두값으로 이뤄진 구간

- 처음 값과 끝 값 사이에 ..연산자를 사용하여 표시한다.

* ..연산자는 숫자뿐 아니라 문자에도 사용할 수 있다. ex) 'A'..'Z'

val n = 1..10

- downTo 함수를 통해 역방향으로 가능하다. (..연산자를 대신하여 쓴다.)

val n = 10 downTo 1

 

수열(Progression): 범위에 속한 값을 일정한 순서로 이터레이션(반복, Iteration)

- step함수를 사용하여 증감할 값을 조절할 수 있다.

val n = 1..10 step 2
// 1 3 5 7 9
val n = 10 downTo 1 step 2
// 10 8 6 4 2

맵, 리스트에 대한 이터레이션(Iteration)

val binbaryReps = TreeMap<Char, String>()
...
for ( (key, value) in binbaryReps) { // 맵에 대한 이터레이션
    println("$key = $value")
}
val list = arrayListOf("10", "11", "1001")
for ((idx, ele) in list.withIndex()) {
    println("$idx: $ele")
}

위 두개의 코드를 보면 맵에선 binbaryReps 안의 key, value를 for문을 통해 반복시키고, List에선 위치와, 요소를 반복시키며 출력한다.

in으로 컬렉션이나 범위 원소 검사

in을 contains함수와 유사하며 어떤 값이 범위나 컬렉션에 속하는지 검사할 수 있다.

5 in 1..10
println("Kotlin in setOf("Java", "C++", "Kotlin")")
// true
728x90

댓글