**範囲(Range)および進行(Progression)**は、特定のステップを持つ値のシーケンスを表すためのKotlinの組み込みメカニズムです。これらは、ループ、条件、コレクションの反復、およびデータのバリデーションを扱う際に頻繁に使用されます。Rangeは、Kotlinの構文をJavaに比べてより簡潔で表現力豊かにする方法の1つとして登場しました。
Javaでは、類似のタスクはforおよびwhileループをインデックスと共に使用して解決されており、冗長でありエラーが発生しやすいものでした。Kotlinでは、範囲を作成するためのコンパクトな演算子(例えば、1..10)やステップを指定するためのメソッドが登場しました。
Kotlinは標準の数値範囲(IntRange、LongRange、CharRange、UIntRangeなど)を提供し、独自の進行を作成するためのインターフェースを提供しています:
コード例:
for (i in 1..5) print("$i ") // 1 2 3 4 5 for (i in 5 downTo 1 step 2) print("$i ") // 5 3 1 // 値のチェック val x = 42 if (x in 1..100) println("範囲内です!")
独自のタイプの範囲を定義することができ、演算子rangeToおよびProgressionを実装します:
data class Version(val major: Int, val minor: Int) : Comparable<Version> { override fun compareTo(other: Version) = compareValuesBy(this, other, Version::major, Version::minor) } operator fun Version.rangeTo(other: Version) = VersionRange(this, other) class VersionRange( override val start: Version, override val endInclusive: Version ) : ClosedRange<Version> for (v in Version(1, 0)..Version(1, 2)) println(v)
主な特徴:
start..end、downTo、step)。in、!in)の組み込み。1..5という式は実際には何を返しますか?
それは、ClosedRange<Int>インターフェースを実装するIntRangeクラスのインスタンスを作成します。これはコレクションではなく、境界とステップを定義するオブジェクトです。遅延実装です。
なぜRangeのステップは常に1ですか?ステップを変更するにはどうすればよいですか?
デフォルトで、範囲のステップは1(またはdownToの場合は-1)です。他のステップを使用するには、stepとdownToメソッドを使用します。例えば:
for (i in 2..10 step 2) println(i)
Comparableを実装していない型と範囲を使用できますか?
いいえ、カスタム範囲が正しく機能するためには、型はComparableインターフェースを実装する必要があります。さもなければ、演算子rangeToは機能しません。
stepメソッドを使用せずにRangeのステップを変更しようとする。開発者がdownToなしでforループ(i in 5..1)を使用し、"5, 4, 3, 2, 1"を期待するが、実際にはループは一度も実行されない。
利点:
欠点:
適切な間隔を持つレポートを反復処理するためにdownToとstepを使用し、コードをコンパクトで自己文書化させる。
利点:
欠点: