自作で作成したクラスでもfor in でループを回したいときがあると思うので、その方法を調べてみました!
公式ドキュメントより引用
https://kotlinlang.org/docs/reference/control-flow.html#for-loops
メンバ関数もしくは拡張関数である itrator() を持っていること。 そしてそれが返す型が
メンバ関数もしくは拡張関数である next() を持っており、
メンバ関数もしくは拡張関数であり、Boolean を返す hasNext() を持っていること。それら3つの関数全てが operator としてマークされていること。
@sdkei さんのコメントを引用
要するに3つのメンバ、関数を実装すればいいってことですね。
繰り返されるクラスに直接Iterableを実装(従来のJavaとほぼ同じ)
class Hoges : Iterable<String> {
override fun iterator(): Iterator<String> {
return object : Iterator<String> {
override fun hasNext(): Boolean {
return true
}
override fun next(): String {
return "hoge"
}
}
}
}
Iteratorインスタンスを返す拡張関数を定義
class Hoges {
}
operator fun Hoges.iterator(): Iterator<String> {
return object : Iterator<String> {
override fun hasNext(): Boolean {
return true
}
override fun next(): String {
return "hoge"
}
}
}
hasNext、nextをプロパティとして定義
class Hoges {
}
operator fun Hoges.iterator() = this
operator fun Hoges.hasNext(): Boolean {
return true
}
operator fun Hoges.next(): String {
return "hoge"
}
メンバとして定義するのでも良いと公式ドキュメントに記載があったもののそれはどうやればいいのかわかりませんでした。。。
従来のJavaのようにIterableを実装するだけでなく、拡張関数としても定義しても良いというのがKotlinらしいですし、
拡張関数ならばライブラリとして提供されていて自分でIterableを実装できないクラスでもfor inに対応できます!
ですが、従来式のIteratorを実装するほうがIntelljIDEAのサジェストで何を実装すればいいのかわかりやすいため個人的にはそちらの方がおすすめです。
参考
https://kotlinlang.org/docs/reference/control-flow.html#for-loops