본문 바로가기
STUDY/Kotlin

Kotlin / Conditions and Loops (If, When, For, While)

by HR_J 2024. 4. 30.

when문을 사용하다, 이런 문법도 되는걸까? 싶은 부분이 있어 Kotlin Docs를 살펴보게 되었다. 그 김에 해당 페이지를 번역하는 겸 개인 공부를 하는 시간을 조금 가졌다.

사람은 모르면 역시, 공식 문서를 읽어봐야합니다.


 

If

코틀린에서, if 표현식은 : value를 반환한다. 그렇기 때문에, 삼항연산자(condition ? then : else) 가 없다. 왜냐하면, if로 충분히 해당 역할을 할 수 있기 때문이다. → if문과 else문이 직접 값을 반환.

만약 사용하고 있다면, 당신은 java style의 코드를 작성하고 있는 것이다.

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

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

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

// You can also use `else if` in expressions:
val maxLimit = 1
val maxOrLimit = if (maxLimit > a) maxLimit else if (a > b) a else b

표현식 의 분기는 if블록이 될 수 있습니다. 이 경우 마지막 표현식은 블록의 값입니다.

val max = if (a > b) {
    print("Choose a")
    a
} else {
    print("Choose b")
    b
}

if예를 들어 값을 반환하거나 변수에 할당하기 위해 표현식으로 사용하는 경우 else분기는 필수입니다.

When

when은 여러 분기가 있는 조건식을 정의한다. C언어의 switch 명령문과 유사한 형태를 갖고 있다. 간단한 형태는 아래와 같다.

when (x) {
    1 -> print("x == 1")
    2 -> print("x == 2")
    else -> {
        print("x is neither 1 nor 2")
    }
}
enum class Bit {
    ZERO, ONE
}

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

when 문에서 else 분기는 다음의 경우에 필수적이다.

  • Boolean, enum, sealed, nullable
enum class Color {
    RED, GREEN, BLUE
}

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

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

여러 사례에 대한 공통 동작을 정의하려면 해당 조건을 쉼표를 사용해 한줄에 결합한다.

when (x) {
    0, 1 -> print("x == 0 or x == 1")
    else -> print("otherwise")
}

Range : in 이나 !in 또한 조건으로 사용할 수 있다.

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")
}

smart cast 덕분에 추가 확인 없이 is, !is 유형의 메서드와 속성에 접근할 수 있다.

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

when은 if-else문을 대체할 수 있다. 아무런 요소가 제공되지 않을 경우, 브랜치의 상태는 boolean 표현식과 같아진다. (true, false 가능)

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

*capture : Closure 밖의 변수를 Closure 안에서 사용하게 되면 그 변수가 capture 되었다고 한다.

fun Request.getBody() =
    when (val response = executeRequest()) {
        is Success -> response.body
        is HttpError -> throw HttpException(response.status)
    }

For Loops

for문은 반복자를 제공하는 모든 항목을 반복한다. 구문은 아래와 같다.

for (item in collection) print(item)

for문의 body는 블록 형태가 될 수도 있다.

for (item: Int in ints) {
    // ...
}

for : 반복할 수 있는 모든 것을 통해 반복 →{

  1. iterator() 멤버 또는 확장 함수가 있는데, 이는 **Iterator<>**를 반환합니다.
  2. **next()**라는 멤버 또는 확장 함수가 있습니다.
  3. **hasNext()**라는 멤버 또는 확장 함수가 있으며, 이는 Boolean 값을 반환합니다.

이 세 함수 모두 연산자로 표시되어야 합니다.

}

숫자 범위를 반복하기 위해선 범위 표현식을 사용하는 것이 좋다.(범위 표현식은 추후에 정리)

for (i in 1..3){
    println(i)
}
for (i in 6 downTo 0 step 2) {
    println(i)
}

범위나 배열에 대한 for 루프는 일반적으로 반복자 객체를 생성하지 않는 인덱스 기반 루프로 컴파일된다.

인덱스가 있는 배열, 목록 반환 방법.

for (i in array.indices) {
    println(array[i])
}

withIndex 라이브러리 사용.

for((index, value) in array.withIndex()) {
	println("$index의 요소는 $value 입니다.")
}

While Loops

while과 do-while 반복문은 조건을 만족할 경우에만 body를 실행시킨다. 둘의 차이점은 상태를 확인하는 시간이다.

  • while 은 조건을 확인하고 만족 하는 경우에 body를 실행한 후 다시 조건을 확인하러 돌아간다.
  • do-while은 body를 먼저 실행한 후 조건을 확인한다. 조건을 만족할 경우 루프가 반복 된다. 그렇기 때문에 do-while문은 조건에 관계 없이 최소 1회 실행된다.
while (x > 0) {
    x--
}

do {
    val y = retrieveData()
} while (y != null) // y is visible here!

Break and Continue in Loops

Kotlin은 루프에서 기존 연산자 break와 연산자를 지원한다.

 

 

참고

 

'STUDY > Kotlin' 카테고리의 다른 글

Kotlin / Scope Function - 범위 지정 함수  (0) 2024.05.31
Kotlin / 숫자 야구 게임  (0) 2024.04.30
Kotlin / 고차함수와 람다  (0) 2024.04.25
Kotlin / 고차함수  (0) 2024.04.24
Kotlin / 계산기 만들기  (0) 2024.04.22