[Kotlin] 2-3. 흐름 제어

흐름 제어 : if, when, for, while

if식

코틀린에서 if는 식(expression)으로, 값을 리턴한다. 그래서 삼항 연산자(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) {
    println("choose a")
    a
} else {
    println("choose b")
    b
}

문장이 아닌 식으로 if를 사용하면(예를 들어 식의 값을 리턴하거나 변수에 값을 할당), else 브랜치를 가져야 한다

when식

when은 C와 같은 언어의 switch연산에 해당

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

when은 특정 브랜치의 조건을 충촉할 때까지 순차적으로 모든 브랜치의 인자가 일치하는지 확인
when은 식이나 문장으로 사용 가능

모든 when 브랜치가 충족하지 않으면 else 브랜치를 평가
when을 식으로 사용시, 모든 경우를 브랜치 조건으로 환인했는지 컴파일러가 알 수 없는 경우 else 브랜치 필수로 추가

여러 경우를 동일한 방법으로 처리할 경우 브랜치 조건을 콤마로 묶을 수 있다

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

브랜치 조건으로 (상수뿐만 아니라) 임의의 식을 사용 가능

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

in, !in, 범위, 콜렉션을 사용해서 값을 검사 가능

when(x) {
  in 1..10 -> println("x is in the range")
  in validNumbers -> println("x is valid")
  !in 10..20 -> println("x is out of the range")
  else -> println("none of the above")
}

is나 !is로 특정 타입 여부를 확인 가능 / 스마트 변환 덕분에 추가 검사 없이 메서드와 프로퍼티에 접근 가능

fun hasPrefix(x: Any) = when(x) {
  is String -> x.startsWith("prefix")  // startsWith() : 문자열이 특정 문자열로 시작하는지 확인
  else -> false
}

if - else if 체인 대신에 when을 사용할 수도 있음
인자를 제공하지 않으면 브랜치 조건은 단순한 블리언 식이 되고, 브랜치 조건이 true일 때 브랜치를 실행

when {
  x.idOdd() -> println("x is odd")
  x.isEven() -> println("x is Even")
  else -> println("x is funny")
}

for루프

for는 이터레이터를 제공하는 모든 것에 대해 반복을 수행한다 / forEach와 동일

for(item in collection) print(item)

몸체는 블록일 수 있다

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

for는 이터레이터를 제공하는 모든 것에 동작

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

“범위에 대한 반복”은 최적화한 구현으로 컴파일해서 객체를 추가로 생성하지 않는다
indices대신 withIndex라이브러리 함수를 사용해도 된다

for((index, value) in array.withIndex()) {
    println("the element at $index is $value")
}

while루프

while과 do..while

while(x > 0) {
    x--
}

do {
    val y = retrieveData()
} while (y != null)  // 여기서 y를 사용할 수 있다

루프에서의 break와 continue

코틀린은 루프에서 전통적인 break와 continue연산자 지원