Kotlin Range Iterator létrehozása egyéni objektumon

1. Bemutatkozás

Egy korábbi cikkünkben bemutattuk, hogyan hozhatunk létre tartományt Kotlinban, és mennyire könnyű iterálni Int, Hosszú és Char típusok.

De mi van, ha akarjuk iterálni egy egyedi típus felett? Lehetséges? A válasz igen! Tehát ugorjunk be a kódba, és nézzük meg, hogyan.

2. Színes típus

Képzeljük el, hogy van egy egyszerű osztályunk, amely RGB színt képvisel:

class CustomColor (val rgb: Int): Összehasonlítható {} 

Jó lenne, ha képesek lennének az RGB színek sokféle változatára:

val a = CustomColor (0x000000) val b = CustomColor (0xCCCCCC) (cc a..b-ben) {// dolgokat csinál}

3. Gyors áttekintés IntRange

Egyszerűen fogalmazva, végre kell hajtanunk Hasonló, Iterálható, és ClosedRange. Előző cikkünkből már tudjuk, hogy végre kell hajtanunk Hasonló.

A másik két interfésznél merüljünk el a IntRange osztálynyilatkozat néhány tippre:

nyilvános osztály IntRange (kezdet: Int, endInclusive: Int): IntProgression (start, endInclusive, 1), ClosedRange 

És akkor, IntProgressionNyilatkozata azt mutatja, hogy végrehajtja Iterálható:

nyilvános nyílt osztály IntProgression: Iterable

Tehát valami hasonlót akarunk tenni ennek érdekében.

4. Színválaszték Osztály

Mint IntRange, hozzunk létre egy Színválaszték osztály.

Céljainkhoz kihagyjuk az utánzást IntProgression, azóta is jól vagyunk, ha az alapértelmezett lépés 1. Ez kissé leegyszerűsíti a dolgokat, és lehetővé teszi számunkra, hogy egyszerűen mindkettőt megvalósítani ClosedRange és Iterálható közvetlenül:

class ColorRange (felülbírálja a val startot: CustomColor, felülbírálja a val endColor: CustomColor): ClosedRange, Iterable {override fun iterator (): Iterator {return ColorIterator (start, endInclusive)}}

A iterátor (), visszatérünk a ColorIterator osztály, amely meg fogja valósítani a nehéz emelést, ha valóban átlépi a hatótávolságot.

Mivel Színválaszték végrehajtja a ClosedRange interfészt, meg kell valósítanunk a összehasonlítani módszer be CustomColor osztály:

felülírja a szórakoztató CompareTo (egyéb: CustomColor): Int {return this.rgb.compareTo (other.rgb)}

5. ColorIterator Osztály

ColorIterator az utolsó darab a rejtvény:

osztály ColorIterator (val start: CustomColor, val endInclusive: CustomColor): Iterator {var initValue = start override fun hasNext (): Boolean {return initValue <= endInclusive} override fun next (): CustomColor {return initValue ++}}

Vegye figyelembe, hogy initValue típusú CustomColor. Tehát, hogy mutálja a ++ operátor, hozzá kell adnunk a inc () módszer a CustomColor is:

operator fun inc (): CustomColor {return CustomColor (rgb + 1)}

6. Az Egyéni tartomány használata

Majdnem ott vagyunk!

Mivel meghatározzuk egyéni tartományunkat, CustomColor osztálynak végre kell hajtania a rangeTo módszer. A rangeTo módszer lehetővé teszi számunkra, hogy a tartományon belül iteráljunk a .. operátor, valahogy olyan, mint a hozzáadás inc lehetővé teszi számunkra a ++ operátor.

Nézzük meg a végterméket:

class CustomColor (val rgb: Int): Összehasonlítható {felülírja a szórakozást összehasonlítandó (egyéb: CustomColor): Int {return this.rgb.compareTo (other.rgb)} operátor szórakoztató tartományTo (hogy: CustomColor) = ColorRange (ez, az) operátor fun inc (): CustomColor {return CustomColor (rgb + 1)}}

És csak erre van szükségünk!

Végül nézzük meg, hogyan működik ez az egész együtt egy sorunk felhasználásával CustomColor osztály:

@Test fun assertHas10Colors () {assertTrue {val a = CustomColor (1) val b = CustomColor (10) val range = a..b for (cc in range) {println (cc)} range.toList (). Size = = 10}}

Ebben a tesztben meghatároztuk a hatótávolság változó és használják az iterációra a CustomColor objektumokat, valamint átalakítsa listává.

Lássunk egy másik példát a szabvány használatára tartalmazza módszer a tartományban:

@Test fun assertContains0xCCCCCC () {assertTrue {val a = CustomColor (0xBBBBBB) val b = CustomColor (0xDDDDDD) val range = a..b range.contains (CustomColor (0xCCCCCC))}}

7. Következtetés

Kotlin natív megvalósítási tartománya a Int, Hosszú és Char értékek. Ebben a cikkben megtanultuk, hogyan lehet egy tartományt egyéni osztályon megvalósítani.

Mint mindig, a kód is elérhető a GitHubon.