Kotlinでは、最初から数値の連続したセットとの操作を簡素化するために範囲(Range)が導入されました。これは、数値の操作時に簡潔な構文を持つ言語(たとえば、Python)から継承されたものです。さらに、RangeのメカニズムはProgressionに拡張され、反復のステップを設定し、さまざまなタイプの数値や文字をサポートできるようになりました。
整数、文字、時間点などを反復する際は、特別な構文と標準ライブラリによる信頼できるサポートがしばしば必要であり、そうでない場合、コードは冗長になり、可読性が低下し、境界に関するエラーが生じやすくなります。
Kotlinには、標準のIntRange、CharRange、LongRangeがあり、また、ステップ反復用のProgressionもあります。さらに、任意のComparable型の範囲を定義することもできます。
// 単純な範囲 for (i in 1..5) print(i) // 12345 // ステップ付き範囲 for (i in 1..10 step 2) print(i) // 13579 // 逆範囲 for (i in 5 downTo 1) print(i) // 54321 // 独自の範囲(例:Versionのため) data class Version(val major: Int, val minor: Int): Comparable<Version> { override fun compareTo(other: Version): Int = compareValuesBy(this, other, Version::major, Version::minor) } operator fun ClosedRange<Version>.iterator(): Iterator<Version> = object : Iterator<Version> { var current = start override fun hasNext() = current <= endInclusive override fun next() = current.also { current = Version(current.major, current.minor + 1) } } val v1 = Version(1, 0) val v2 = Version(1, 3) for (v in v1..v2) println(v)
主な特徴:
.., downTo, until, step1..5 と 1 until 5 の違いは何ですか?
1..5は範囲の両端を含みます:1,2,3,4,5。1 until 5は最後の要素を含みません:1,2,3,4。
ステップを使用して0未満のステップの範囲を設定できますか?
いいえ。減少する範囲にはdownTo構造を使用し、その後にステップを設定します:5 downTo 1 step 2(5,3,1を得ます)。
Comparableを実装していない型で範囲を使用できますか?
いいえ。範囲を作成するためには、型が比較をサポートしている必要があります。そうでない場合、コンパイラは定義を許可しません。
..ではなくuntilを使用する、あるいはその逆、境界の包含に混乱コードで1 until n+1の代わりに1..nを使用しました。余分な要素が得られ、ループが範囲の境界を越えます。
利点:
欠点:
配列の長さnに対するインデックス付けにfor (i in 0 until n)を使用しています。範囲は有効なインデックス値と厳密に一致します。
利点:
欠点:
..とuntilの違いを覚えておく必要があります。