흐름 제어 : 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은 식이나 문장으로 사용 가능
- 식으로 사용시, 충족한 브랜치의 값이 전체 식의 값
- 문장으로 사용시, 개별 브랜치의 값은 무시(if처럼 각 브랜치는 블록 가능, 블록의 마지막 식의 값이 브랜치 값)
모든 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는 이터레이터를 제공하는 모든 것에 동작
- iterator() 멤버 함수나 확장 함수를 갖고 있고, 함수 리턴 타입이
- next() 멤버 함수나 확장 함수를 갖고,
- 리턴 타입이 Boolean인 hasNext() 멤버 함수나 확장 함수를 가짐
이 세 함수는 모두 operator로 지정
배열에 대한 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연산자 지원