Binary World

제어 흐름(Control Flow) 본문

개발자의 길/Kotlin

제어 흐름(Control Flow)

모쿠 2019. 5. 28. 22:12

If 표현식

Kotlin에서 if는 표현식이다. 즉, 값을 반환한다. 그러므로 삼중 연산자 (condition? then : else)가 없다. 왜냐하면 if가이 역할을 잘 수행하기 때문이다.

// 기존 사용법
var max = a 
if (a < b) max = b

// else를 사용하여 
var max: Int
if (a > b) {
    max = a
} else {
    max = b
}
 
// 표현식으로
val max = if (a > b) a else b

if분기가 블록 일 수 있고, 마지막 표현식이 블록의 값인 경우

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

 

When 표현식

when은 C언어 계열의 스위치 연산자를 대신한다. 가장 간단한 형태로 보면 다음과 같다.

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

when은 분기 조건이 충족될 때까지 모든 분기에 대한 인수 값을 순차적으로 찾는다. when은 표현식이나 명령문으로 사용될 수 있다. 표현식으로 사용되면 만족 된 분기의 값이 전체 표현식의 값이 된다. 명령문으로 사용되면 개별 분기의 값은 무시된다.

다른 분기 조건이 충족되지 않으면 else 분기가 평가된다. 컴파일러가 가능한 모든 경우가 분기 조건으로 덮여 있다는 것을 증명할 수 없다면, 표현식으로 when을 사용하면 else 분기는 필수 조건이다. 

 

많은 경우가 동일한 방식으로 처리되어야하는 경우, 분기 조건은 쉼표로 결합할 수 있다.

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

분기 조건으로 임의의 표현식 (상수뿐만 아니라)을 사용할 수 있다.

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

범위의 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")
}

is 또는 !is를 이용하여 값이 특정 유형인지 확인이 가능하다. 스마트 캐스트(Smart cast) 덕분에, 추가 검사 없이 타입의 메소드 및 속성에 접근할 수 있다.

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

 

when은 if-else 체인의 대체용으로도 사용할 수 있다. 인수 값이 제공되지 않으면 분기 조건은 단순히 논리식이 되고, 조건이 참일 때 분기가 실행된다.

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

Kotlin 1.3 이후, 다음과 같은 구문을 사용하여 when의 주체 변수를 얻을 수 있다.

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

변수의 범위에서, when의 주체는 when 몸체로 제한된다.

 

For 반복

for 반복은 반복자를 제공하는 모든 것을 반복한다. 이것은 C# 같은 언어의 foreach 루프와 동일하다. 구문은 다음과 같다.

for (item in collection) print(item)

몸체는 블록화 될 수 있다.

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

앞서 언급했듯이, for는 반복자를 제공하는 모든 것들을 통해 반복된다. 아래 예시가 있다.

  • iterator() 멤버 또는 확장 함수를 갖고 있고, 이는 리턴 타입이 존재
    • next() 멤버 또는 확장 함수를 갖고 있고,
    • 부울을 리턴하는 hasNext() 멤버 또는 확장 함수를 갖고 있다.

위의 세 가지 함수는 operator로 표시되어야 한다.

 

범위 표현을 사용하여, 숫자의 범위 내에 반복하기:

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

/* 출력 결과 */
1
2
3
6
4
2
0

범위 또는 배열에 대한 for 반복은 반복자 객체를 만들지 않는 인덱스 기반 반복으로 컴파일된다.

인덱스가 있는 배열이나 목록을 반복 할 경우 다음과 같이 할 수 있다.:

fun main() {
val array = arrayOf("a", "b", "c")
    for (i in array.indices) {
        println(array[i])
    }
}

/* 출력 결과 */
a
b
c

또는, withIndex 라이브러리 함수를 사용할 수 있다.

fun main() {
    val array = arrayOf("a", "b", "c")
    for ((index, value) in array.withIndex()) {
        println("the element at $index is $value")
    }
}

/* 출력 결과 */
the element at 0 is a
the element at 1 is b
the element at 2 is c

 

While 반복

while 과 do..while 다른 언어와 같이 동작한다.

while (x > 0) {
    x--
}

do {
    val y = retrieveData()
} while (y != null) // y는 여기서 보인다!

 

 

'개발자의 길 > Kotlin' 카테고리의 다른 글

함수(Functions)  (0) 2019.05.30
리턴과 점프(Returns and Jumps)  (0) 2019.05.29
패키지와 임포트(Packages and Imports)  (0) 2019.05.28
기본 타입(Basic Type)  (0) 2019.05.28
기본 구문(Basic Syntax)  (0) 2019.05.28
Comments