다재다능 코틀린 프로그래밍 책으로 코틀린 스터디를 진행하면서 발표를 위해 준비했던 글입니다.
범위와 반복
레인지 클래스
- 1 ~ 5 까지 숫자의 범위 만들기
val oneToFive: IntRange = 1..5
// IntRange 타입이 명확성을 제공해주지만 IntRange를 적지 않아도 타입추론이 가능하다.
- a ~ e 까지 알바벳 만들기
val aToE: CharRange = 'a'..'e'
- 문자열 범위 만들기
val seekHelp: ClosedRange<String> = "hell".."help"
// hell, helm, heln, help
정방향 반복
- 1 ~ 5 반복
for (i in 1..5) { print("$i, ")} // 1, 2, 3, 4 ,5
// 명시적으로 선언하지 않아도 변수 i는 val → 안정적이다.
- a ~ e 반복
for (ch in 'a'..'e') { print(ch) } // abcde
- hell ~ help 반복
for (word in "hell".."help") { print("$word, ") } // ERROR
// IntRange나 CharRange 같은 클래스들은 iterator()함수가 있는데,
// ClosedRange<T>에는 iterator()가 없기 때문, 방법은 있다. 12-2에서 설명할 예정
후방향 반복
- downTo() 메소드를 사용하여 후방향 반복을 쉽게 할 수 있다.
- 5 ~ 1 감소하는 반복
for (i in 5.downTo(1)) { print("$i, ") } // 5, 4, 3, 2, 1
// downTo() 메소드 호출 시 IntProgression 인스턴스를 리턴한다.
// IntProgression은 kotlin.rangs 패키지의 일부
// 12-4에서 코드를 더 간단하게 만들 수 있는 방법을 설명할 예정
- 5 ~ 1 감소하는 반복 개선
for (i in 5 downTo 1) { print("$i, ") } // 5, 4, 3, 2, 1
범위 안의 값 건너 뛰기
- until() 메소드를 사용해서 마지막 값을 포함시키지 않을 수 있다.
for (i in 1 until 5) { print("$i, ") } // 1, 2, 3, 4,
- 값을 건너뛸 때
i = i + 3
같은 식은 코틀린에서는 불가능, i 가 기본적으로 val 이기 때문 - step() 메소드를 사용하여 값을 건너뛸 수 있다.
for (i in 1 until 10 step 3) { print("$i, ") } // 1, 4, 7,
- 역방향 반복 값 건너 뛰기
for (i in 10 downTo 0 step 3) { print("$i, ") } // 10, 7, 4, 1
- filter() 메소드를 사용해 순차적이지 않은 값을 건너뛸 수 있다.
- 3의 배수나 5의 배수만 반복하기
for (i in (1..9).filter { if % 3 == 0 || it % 5 == 0 }) {
print("$i, ") // 3, 5, 6, 9
}
배열과 리스트의 반복
- arrayOf() 함수를 사용해 배열을 만들 수 있다.
val array = arrayOf(1, 2, 3)
for (e in array) { print("$e, ") }
- 원시 자료형인 Int 배열을 생성하기 위해선 intArrayOf() 메소드를 사용하면 된다.
- listOf() 메서드를 사용해서 List를 만들 수 있다.
val list = listOf(1, 2, 3)
println(list.javaClass) // ArrayList
for (e in list) { print("$e, ") } // 1, 2, 3
- 인덱스가 필요할때의 반복문
val names = listOf("Tom", "Jerry", "Spike")
for (index in names.indices) {
println("Position of ${names.get(index)} is $index")
}
// Position of Tom is 0
// Position of Jerry is 1
// Position of Spike is 2
- withIndex() 함수를 사용해서 인덱스와 value 얻기
val names = listOf("Tom", "Jerry", "Spike")
for ((index, name) in names.withIndex()) {
println("Position of $name is $index")
}
when을 사용해야 할 때
- 코틀린에는 switch 대신 when이 있다.
표현식으로서의 when
fun isAlive(alive: Boolean, numberOfLiveNeighbors: Int) = when {
numberOfLiveNeighbors < 2 -> false
numberOfLiveNeighbors > 3 -> false
numberOfLiveNeighbors == 3 -> true
else -> alive && numberOfLiveNeighbors == 2
}
- 단일 표현식 함수 문법 사용 → 리턴 타입 추론
- when은 if에 비해서 간결하다.
- when에서 모든 입력에 대한 값을 생성하는지 또는 else가 있는지 컴파일 타임 체크를 해준다.
- Any 타입 파라미터를 받는 메소드에서 when에 값이나 표현식 전달하기
fun whatToDo(dayOfWeek: Any) = when (dayOfWeek) {
"Saturday", "Sunday" -> "Relax"
in listOf("Monday", "Tuesday", "Wednesday" "Thursday") -> "Work hard"
in 2..4 -> "Work hard"
"Friday" -> "Party"
is String -> "What?"
else -> "No clue"
}
println(whatToDo("Sunday")) // Relaxy
println(whatToDo("Wednesday")) // Work hard
println(whatToDo(3)) // Work hard
println(whatToDo("Friday")) // Party
println(whatToDo("Munday")) // What?
println(whatToDo(8)) // No clue
- when에서 else가 마지막이 아닌 다른 곳에 오는 것은 허용하지 않는다.
- → 뒤에 블록{}이 오는 것이 허용되지만 가독성 측면에서는 이용하지 않는게 좋다. → 단일 표현식에 메소드를 호출하는 방식으로 사용하자.
명령문으로써의 when
fun printWhatToDo(dayOfWeek: Any) {
when (dayOfWeek) {
"Saturday", "Sunday" -> println("Relax")
in listOf("Monday", "Tuesday", "Wednesday" "Thursday") -> println("Work hard")
in 2..4 -> println("Work hard")
"Friday" -> println("Party")
is String -> println("What?")
}
printWhatToDo("Sunday") // Relaxy
printWhatToDo("Wednesday") // Work hard
printWhatToDo(3) // Work hard
printWhatToDo("Friday") // Party
printWhatToDo("Munday") // What?
printWhatToDo(8) //
- else가 없어도 상관 없는 이유: 리턴타입이 Unit이기 때문
- 즉 when이 명령문으로 사용될 때는 else가 없어도 상관없다.
when과 변수의 스코프
- val을 분리
fun systemInfo(): String {
val numberOfCores = Ruintime.getRuntime().availableProcessors()
return when (numberOfCores) {
1 -> "1 core, ..."
in 2..15 -> "You have $numberofCores cores"
else -> "$numberOfCores cores!..."
}
}
- val을 when 인자로 넣기
fun systemInfo(): String =
return when (val numberOfCores = Ruintime.getRuntime().availableProcessors()) {
1 -> "1 core, ..."
in 2..15 -> "You have $numberofCores cores"
else -> "$numberOfCores cores!..."
}
- val을 when 인자로 넣으면 짧은 코드를 만들 수 있다.
- numberOfCores는 when의 결과를 얻을 때만 사용가능하고 이후 연산에서는 사용이 불가능
- 변수의 스코프를 제한하는 것은 좋은 디자인
'스터디 > 다재다능 코틀린 프로그래밍' 카테고리의 다른 글
6. 오류를 예방하는 타입 안전성 (0) | 2021.11.29 |
---|---|
5. 콜렉션 사용하기 (0) | 2021.11.29 |
3. 함수를 사용하자. (0) | 2021.11.29 |
2. 코틀린 필수 사항 (0) | 2021.09.02 |
1. 왜 코틀린을 선택해야 하는가? (0) | 2021.09.02 |