일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | 6 | 7 |
8 | 9 | 10 | 11 | 12 | 13 | 14 |
15 | 16 | 17 | 18 | 19 | 20 | 21 |
22 | 23 | 24 | 25 | 26 | 27 | 28 |
29 | 30 |
- 세그먼트 트리
- swea
- 이분탐색
- java
- 프로그래머스
- 위상정렬
- 수학
- dfs
- 유니온 파인드
- 플로이드-와샬
- 후니의 쉽게 쓴 시스코 네트워킹
- 그리디
- 백준
- 구현
- CS
- 동적계획법
- 백트래킹
- 투 포인터
- Network
- 완전탐색
- 스택
- mst
- JUnit 5
- BFS
- Effective Java
- 알고리즘
- Kotlin
- 에라토스테네스의 체
- 문자열
- 시뮬레이션
반갑습니다!
[Kotlin] 반복문 본문
일반적인 프로그래밍 언어에서 지원하는 반복문을 코틀린에서도 지원한다.
for문
자바에서 사용하던 반복문은 for(int i=0; i<10; i++)
의 형태를 가졌다. 코틀린에서는 이를 조금 더 축약하여 for(i in 0..9)
로 사용할 수 있다. 이 때 주의해야할 것은 0..9
는 0이상 9이하의 범위를 의미한다. 즉, <=
를 의미하는 것이다. 코틀린에서 0이상 10미만의 범위를 나타내기 위해서는 until
키워드를 사용해서 0 until 10
로 표현하면 된다.
반복문은 어렵지 않기 때문에 예시를 통해 알아보고 넘어가겠다.
fun main() {
for(i in 0..10) print("$i ")
println()
for(i in 1 until 10) print("$i ")
println()
for(i in 0..10 step 2) print("$i ")
println()
for(i in 10 downTo 0) print("$i ")
println()
}
/*
실행 결과
0 1 2 3 4 5 6 7 8 9 10
1 2 3 4 5 6 7 8 9
0 2 4 6 8 10
10 9 8 7 6 5 4 3 2 1 0
*/
while문
while문은 while(조건)으로 구성되어있다. 조건이 True인 경우에 반복문을 수행한다.
fun main() {
var i = 1
while (i < 10) {
print("${i++} ")
}
println()
}
/*
실행 결과
1 2 3 4 5 6 7 8 9
*/
do while문
while문과 조금 다른 do while문이 있다. while문은 조건검사를 하고 반복문을 들어가지만, do while문은 실행한 뒤, 조건을 검사한다는 차이점이 있다.
반복문의 흐름 제어
return의 사용
함수에서 return을 사용하게 되면 return의 아래에 있는 코드들은 실행되지 않는다.
fun main() {
retFunc()
}
inline fun inlineLambda(a: Int, b: Int, out: (Int, Int) -> Unit) {
out(a, b)
}
fun retFunc() {
println("start of retFunc")
inlineLambda(13, 3) { a, b ->
val result = a + b
if(result > 10) return
println("result: $result")
}
println("end of retFunc")
}
/*
실행 결과
Start of retFunc
*/
다음과 같은 코드가 있다고 가정하자. a + b가 10보다 크면 람다 함수를 종료하고 싶다. 하지만 위의 코드에서는 "start of retFunc" 만 출력될 뿐, "end of retFunc"는 출력되지 않는다. 이는 람다 함수에서의 return이 retFunc()
를 종료시켰기 때문이다. 이를 비지역반환이라고 한다. 비지역반환을 방지하기 위해서는 '라벨'을 사용하면 된다. 라벨을 붙일 때는 (라벨 이름)@
, 라벨을 호출할 때는 @(라벨 이름)
으로 사용한다.
fun main() {
retFunc()
}
inline fun inlineLambda(a: Int, b: Int, out: (Int, Int) -> Unit) {
out(a, b)
}
fun retFunc() {
println("Start of retFunc")
inlineLambda(13, 3) label@{ a, b ->
val result = a + b
if (result > 10) return@label
println("result: $result")
}
println("end of retFunc")
}
/*
실행 결과
Start of retFunc
end of retFunc
*/
위의 코드처럼 라벨을 사용하면 흐름 제어를 조금 더 편리하게 할 수 있다. 라벨을 사용하면서 값을 반환하기 위해서는 return@a 1
와 같이 사용하면 된다.
또한 람다식 표현식 블록에 직접 라벨을 쓰지 않고 람다식 함수의 명칭을 그대로 라벨처럼 사용할 수 있는데 이것을 암묵적 라벨이라고 부른다.
fun retFunc() {
println("start of retFunc")
inlineLambda(13, 3) { a, b ->
val result = a + b
if(result > 10) return@inlineLambda
println("result: $result")
}
println("end of retFunc")
}
위의 내용에서 라벨을 사용하여 비지역반환을 방지하는 방법을 알아보았다. 비지역반환을 방지하는 다른 방법이 있는데 이는 익명 함수를 사용하는 방법이다.
fun main() {
retFunc()
}
inline fun inlineLambda(a: Int, b: Int, out: (Int, Int) -> Unit) {
out(a, b)
}
fun retFunc() {
println("Start of retFunc")
inlineLambda(13, 3, fun(a: Int, b: Int) {
val result = a + b
if (result > 10) return
println("result: $result")
})
println("end of retFunc")
}
/*
실행 결과
Start of retFunc
end of retFunc
*/
이와 같이 익명 함수를 선언하게 되면 return을 하더라도 익명 함수만 종료되기 때문에 비지역반환이 발생하지 않는다.
break / continue
다른 프로그래밍 언어에서처럼 코틀린 역시 break와 continue를 지원한다. 그리고 break와 continue 역시 라벨을 사용하여 흐름 제어를 할 수 있다.
fun labelBreak() {
first@for(i in 1..5) {
second@ for(j in 1..5) {
if (j == 3) break@first
println("i: $i, j: $j")
}
}
'Kotlin' 카테고리의 다른 글
[Kotlin] Coroutine Basics (0) | 2020.07.04 |
---|---|
[Kotlin] Coroutine Guide (0) | 2020.07.04 |
[Kotlin] 조건문 (0) | 2020.06.15 |
[Kotlin] 함수형 프로그래밍 (0) | 2020.06.09 |
[Kotlin] 함수 (0) | 2020.06.09 |