💡 if-else 문
- if 문이 '식'으로 사용되는 경우 값을 반환한다.
- if '식'의 경우 반다시 else를 동반해야 하지 않으면 컴파일 에러가 난다.
// a가 큰경우 max에 a를 대입, 아니면 b 대입
// 상항연산자와 구조가 동일하다
val max = if (a > b) a else b
- if '식'의 branches들이 블록을 가질 수 있다. { ... }
- 블록의 마지막 구문이 반환값이 된다.
fun if_else_식() {
var a = 5
var b = 4
val max = if (a > b) {
print("Choose a")
a // 블록의 마지막 구문인 a가 반환값이 된다
} else {
print("Choose b")
b // 블록의 마지막 구문인 b가 반환값이 된다
}
}
그리고 코틀린에는 삼항연산자가 없다.
왜냐하면 if가 삼항연산자의 역할을 잘 해내기 때문이다.
💡 when 문
- C계열 언어의 switch문을 대체한다.
- 각각의 Branches의 조건문이 만족할 때까지 위에서부터 순차적으로 인자를 비교한다.
- 조건이 맞으면 맞는 조건의 코드를 출력하기 때문에 break문을 쓸 필요가 없다.
when (x) {
1 -> print("x == 1")
2 -> print("x == 2")
else -> {
print("x is neither i nor 2")
}
}
- when 문도 if식처럼 '식'으로 사용하면 else 문이 필수이다.
- 식으로 사용된 경우 1, 조건을 만족하는 branch의 값이 전체 식의 결과값이 된다.
- 식으로 사용된 경우2 , else가 없어도 된다는걸 컴파일러가 입증하면 else를 생략 가능하다.
var res = when (x) {
100 -> "A"
90 -> "B"
80 -> "C"
else -> "F"
}
// else 문이 없어도 되는 케이스
var res = when (x) {
true -> "맞다"
false -> "틀리다"
}
여러 조건들이 같은 방식으로 처리될 수 있는 경우, 조건문에 ','를 사용하여 표기하면 된다.
when (x) {
0, 1 -> print("x == 0 or x == 1")
else -> print("otherwise")
}
branch의 조건문에 함수나 식을 사용 가능하다.
when (x) {
parseInt(x) -> print("s encodes x")
1 + 3 -> print("4")
else -> print("s does not encode x")
}
range를 줘서 collection에 in이나 !in으로 범위 등을 검증할 수 있다.
val validNums = listOf(3,6,9)
when (x) {
in validNums -> print("x is valid")
in 1..10 -> print("x is in the range")
!in 10..20 -> print("x is outside the range")
else -> print("none of the above")
}
is, !is를 이용한 타입 검증, 이때 스마트 캐스팅이 적용된다.
fun hasPrefix(x: Any) = when (x) {
is String -> x.startsWith("prefix")
else -> false
}
if-else 체인을 완전히 대체할 수 있고, 인자를 입력하지 않으면, 논리연산으로 처리된다.
when {
x.isOdd() -> print("x is odd")
x.isEven() -> print("x is even")
else -> print("x is funny")
}
💡 Loop
for문을 지원하는 iterator의 조건
- 멤버함수나 확장함수 중에 iterator()를 반환하는 것이 있는 경우
- next()를 가지는 경우
- hasNext()를 [Boolean] 가지는 경우
- 위의 3개의 함수는 operator로 표기되어야 함.
핵심은 Iterator를 가지고 있지 않는 MyData 객체가 For Each 문에 들어올 수 있다는 것이다.
일반적인 코틀린의 for문은 iterator를 제공하는 모든 것을 반복할 수 있고, Body에 블럭이 올 수도 있다.
fun 반복() {
var collection = listOf(1,2,3,4,5)
collection.iterator()
for (i in collection)
print(i)
val array = arrayOf(1,2,3,4,5)
array.iterator()
for (i in array)
println("$i: $array[i]")
}
연산자 오버로딩을 이용한 iterator()가 없는 객체 For-Each 구현
여기서 봐야할 중요한 점은,
위에서 말한 조건들을 구현하면 iterator()를 가지고 있지 않는 객체도 For-Each를 돌 수 있다.
// 아래의 두 클래스로 인해
// Iterator를 가지고 있지 않는 MyData 객체가 For Each 문에 들어올 수 있다.
fun main(args: Array<String>) {
val myData = MyData()
myData.iterator()
for (i in myData) {
print(i)
}
}
// next(), hasNext()를 가지고 있는 클래스
class MyIterator {
val data = listOf(1,2,3,4,5)
var idx = 0
operator fun hasNext() : Boolean {
return data.size > idx
}
operator fun next() : Int {
return data[idx++]
}
}
// MyIterator 객체를 반환하는 클래스
class MyData {
operator fun iterator() : MyIterator {
return MyIterator()
}
}
indices & withIndex()
배열이나 리스트를 index를 이용하여 반복하고 싶을때 사용한다.
val array = arrayOf("가", "나", "다")
for (i in array.indices) {
println("$i: ${array[i]}")
}
index를 이용하고 싶을 때, withIndex()를 사용한다.
인덱스와 값이 같이 반환된다.
val array = arrayOf("가", "나", "다")
for ((index, value) in array.withIndex()) {
println("$index: ${value}")
}
While Loop
- whild, do-whild은 자바의 거의 같다.
- do-while의 조건문이 body의 지역변수를 참조할 수 있다.
while (x > 0) {
x--
}
// do 안의 지역변수인 y를 while에서 참조가 가능하다
do {
val y = retrieveData()
} while (y != null) // y is Visible Here !
'Languages > Kotlin' 카테고리의 다른 글
Kotlin - Variable (0) | 2023.04.03 |
---|---|
Extention Function (0) | 2023.03.29 |
[Operator Overloading] 이항 & 단항 산술 연산자 오버로딩 (0) | 2023.03.29 |
[Operator Overloading] 복합 대입 & 비교 연산자 오버로딩 (0) | 2023.03.29 |
Kotlin Basic Types (0) | 2023.03.26 |