for .. in 은 무엇일까
DoDoBest
·2024. 3. 8. 21:32
학습하게 된 계기
코틀린 코루틴 책을 학습하다가 for문에 Channel class를 사용하는 코드를 보고, list도 아닌 class가 어떻게 원소를 반환하는지 궁금해졌다.
suspend fun main(): Unit = coroutineScope {
val channel = Channel<Int>()
launch {
repeat(1) { index ->
println("Producing next one")
delay(1000)
channel.send(index * 2)
}
channel.close()
}
launch {
for (element in channel) {
println(element)
}
}
}
for … in 의 의미
아래와 같은 코드에서 in은 list.iterator()를 호출해서 이터레이터를 얻은 다음, 자바와 마찬가지로 그 이터레이터에 대해 hasNext와 next 호출을 반복하는 식으로 변환된다.
fun main() {
val list = listOf(1,2,3)
for (i in list) {
println(i)
}
}
자바로 디컴파일 된 코드는 다음과 같다. for .. in 문이 while문으로 바뀐 것을 볼 수 있다.
public final class MainKt {
public static final void main() {
List list = CollectionsKt.listOf(new Integer[]{1, 2, 3});
Iterator var2 = list.iterator();
while(var2.hasNext()) {
int i = ((Number)var2.next()).intValue();
System.out.println(i);
}
}
...
}
이것을 통해 Class가 iterator를 반환한다면 클래스 자체를 for .. in 다음에 놓을 수 있다는 것을 알게 되었다.
Iterator는 무엇인가?
Kotlin 공식 문서에서 Iterator를 아래와 같이 소개하고 있다.
For traversing collection elements, the Kotlin standard library supports the commonly used mechanism of iterators – objects that provide access to the elements sequentially without exposing the underlying structure of the collection
https://kotlinlang.org/docs/iterators.html
Iterator는 collection의 내부 구현을 노출하지 않고 collection 원소들에 순차적으로 접근할 수 있도록 도와주는 객체다.
MutableList의 상속 관계를 살펴보면, List와 MutableCollection 인터페이스를 상속하고 있고, 이 둘은 Collection 인터페이스를 상속하며, Collection은 Iterable 인터페이스를 상속한다.
Iterable 인터페이스에 Iterator를 반환하는 함수가 있으며 Iterator는 next, hasNext 함수를 가지고 있는 인터페이스다!
Iterator를 제공하는 클래스는 어떻게 만들 수 있을까?
따라서 iterator 인터페이스를 상속하거나, iterable 인터페이스를 구현하고 iterator 구현체를 반환하는 iterator operator 함수를 클래스에 생성하면 된다.
class Progression: Iterator<Int> {
private var progressStatus = 0
private val maxStatus = 100
override fun hasNext(): Boolean = progressStatus <= maxStatus
override fun next(): Int {
if (progressStatus > maxStatus) throw IllegalStateException()
return progressStatus++
}
}
fun main() {
val progression = Progression()
for (i in progression) {
println(i)
}
}
'학습' 카테고리의 다른 글
EditText가 입력된 text를 복원하는 과정 (0) | 2024.03.20 |
---|---|
자바 Static, Kotlin Companion, 그리고 Annotation의 Function (0) | 2024.03.16 |
Android에서 ConstraintLayout은 왜 사용하는 걸까 (0) | 2024.03.03 |
Android에서 View는 어떻게 그려질까? - 1 (0) | 2024.02.28 |
RecyclerView 공백 ViewHolder 문제 (0) | 2024.02.14 |