4. 흐름 제어 - Control Flow
목차
1. if-else 문
자바와 거의 비슷하다.
1-1. 일반 if문 , if else 문
var max = a
if ( a < b ) max = b // a가 b보다 크면 b를 반환해라.
var max: Int
if ( a > b ) {
max = a // a가 더 크면 max에 a를 넣고.
} else {
max = b // 아니고, b가 더 크다면 max에 b를 넣는다.
}
1-2. 값을 반환하는 if else 문
- if문이 식으로 사용되는 경우 값을 반환한다.
- if식의 경우 반드시 else 를 동반해야 된다.
val max = if ( a > b ) a else b
// if 문이 식으로 사용되었다. 식의 값이 max의 값에 할당하게 된다.
// val max = if (조건) true else false
// 반환값이 없으면 컴파일 에러.
- if식의 브랜치들이 블록을 가질 수 있다. (브랜치란, 식의 if else 문의 식의 블록(구현부)라고 생각하면 된다.)
- 블록의 마지막 구문이 반환 값이 된다.
val max = if ( a > b ) {
print("a print")
a
} else {
print("b print")
b
}
//위와 같은 경우에도 if의 조건이 true면 a를 반환하고, false 면 b를 반환한다.
1-3. 기타 특징
삼항 연산자가 없다. → if else 문이 이미 삼항연산자의 역할을 하기 때문이다.
//java
int max = ( a > b ) ? a : b;
//kotlin
val max = if ( a > b ) a else b
2. when 문
2-1. 기본 when문.
- when문은 C계열 언어의 switch문을 대체한다.
- when문은 각각의 브랜치의 조건문이 만족할 때 까지 위에서 부터 순차적으로 인자를 비교한다.
when (x) {
1 -> print("x == 1")
2 -> print("x == 2")
else -> {
print("x is no 1,2")
}
}
switch문의 brack가 필요없이, 나열하게 되면, 처음부터 비교하다가 맞는것이 나올때까지 실행된다.
마지막의 else는 swich 문의 default라고 생각하면 된다.
2-2. else가 필수인 when문
- when문이 식으로 사용된 경우에, 브랜치의 값이 전체 식의 결과 값이 된다.
- else의 경우 다른 브랜치들이 조건이 만족되지 않을 때에 수행된다.
- when이 식으로 사용된 경우에는 else문이 필수이다.
var score = when(x) {
100 -> "A"
90 -> "B"
80 -> "C"
else -> "F"
}
2-3. else가 생략되어도 되는 when문
- 단, else를 생략할 수 있는 경우도 있는데 이때에는 아래와같이 true / false (boolean 타입) 처럼 2가지중 하나를 입증할 수 있을 경우에는 생략할 수 있다. (컴파일러가 판단)
var score = when(x) {
true -> "100"
false -> "0"
} // true / false 와 같이 두가지 중 하나가 선택되는 경우 else 를 생략할 수 있다.
2-4. 여러 조건이 들어가는 when문
- 여러 조건들이 들어가야된다면, 브런치안에 콤마(,) 를 사용하여 표현하면 된다.
when(x) {
0, 1 -> print("x is 0,1")
else -> print("not find")
}
2-5. 조건문에 함수나 식을 사용하는 when문
- 브랜치의 조건문에 함수나 식을 사용 할 수 있다.
when(x) {
parseInt(x) -> print("parsed x.") //함수도 사용가능.
1 + 3 -> print("4") //식도 사용 가능.
else -> print("not found.")
}
2-6. range나 collection에 in이나 !in(not in)으로 범위등을 검사할 수 있는 when문
val numbers = listOf(3,6,9)
when(x) {
in numbers -> print("x is valid") // 3,6,9 중 하나일때,
in 1..10 -> print("x in 1~10") // 1~10 사이일때,
!in 10..20 -> print("x not in 10~20") // 10~20 사이가 아닐때,
else -> print("not found.") // 모두 아닐경우.
}
2-7. is나 !is를 이용하여 타입도 검사할 수 있는 when문
- 스마트 캐스트가 적용
→ Any(Object)로 받았을때 String으로 검사하는 동시에 startWith라는 함수를 사용가능하게 해준다.
fun main(args: Array<String>){
val value: String = "prefixabc"
print(hasPrefix(value))
}
fun hasPrefix(x: Any) = when(x) {
is String -> x.startsWith("prefix") // prefix로 시작하면, true 반환
else -> false // false반환
}
2-8. when은 if else if 체인 구문을 대체 할 수 있다.
- when문의 인자를 입력하지 않았을때에 if else if else 반복되는 것을 하지 않고 대체가능하다.
var x: Int? = 1
when {
x == 1 -> print("x is 1")
x == 2 -> print("x is 2")
else -> print("x is no 1,2")
}
3. For Loop문 (반복문)
3-1. 기본 For Loop문
- for문은 iterator를 제공하는 모든것을 반복할 수 있다.
list, array 는 .iterator() 를 사용할 수 있다. .iterator()를 반환하지 않는것을 for문에 작성할시 컴파일에러.
for (item in collection)
print(item)
- for문의 Body가 블록이 올 수 있다. (자바처럼)
for (item in collection) {
print(item.id)
print(tiem.name)
}
3-2. For문을 지원하는 iterator의 조건
- iterator()를 반환하는 것이 있는 경우.
- iterator()를 반환 하면서, next()를 가지는 경우
- iterator()를 반환 하면서, hasNext(): Boolean을 가지는 경우.
‼️ 위 3가지 함수가 operator 로 표기되어있어야 함!
- 예시)
fun main(args: Array<String>){
val myData = MyData()
myData.iterator()
for(item in myData) {
print(item)
}
}
class MyIterator {
val data = listOf(1,2,3,4,5)
var idx = 0
operator fun hasNext() : Boolean { // operator 필수~
return data.size > idx
}
operator fun next() : Int { // operator 필수~
return data[idx++]
}
}
class MyData {
operator fun iterator() : MyIterator { // operator 필수~
return MyIterator()
}
}
위 처럼, MyData는 list나 array가 아닌데, for문을 사용할 수 있었던 점은.
Mydata에서 operator로 선언된 iterator()를 반환해야하고,
또, MyIterator안에 operator의 hasNext()와 next()를 반환해야 가능하다.
그렇게 중요하진 않음.... ㅋㅋ
3-3. For문을 돌때 인덱스를 사용하고 싶다면 ?
- indices를 이용한다.
val array = arrayOf("A","B","C")
for (item in array.indices) {
println("$item: ${array[item]}")
}
/*
출력결과
0: A
1: B
2: C
*/
- withIndex()를 이용한다.
val array = arrayOf("A","B","C")
for ((index, value) in array.withIndex()) {
println("$index: ${value}")
}
/*
출력결과
0: A
1: B
2: C
*/
개인적으로 withIndex()가 더 명확한 소스로 보인다.
4. While Loop문 (반복문)
- 자바와 유사하다. while, do-while 모두.
var x : Int = 3
while ( x > 0 ) {
print(x)
x = x-1
}
- do-while문에서 body의 지역변수를 do-while문의 조건문이 참조 할 수 있다.
do {
val y = retrieveData()
} while (y!=null) // y를 참조가능.