Oprettelse af en Kotlin Range Iterator på et brugerdefineret objekt

1. Introduktion

I en tidligere artikel viste vi, hvordan vi kan oprette et interval i Kotlin, og hvor let det er at gentage sig Int, lang og Char typer.

Men hvad hvis vi vil gentage over en brugerdefineret type? Er det muligt? Svaret er ja! Så lad os hoppe ind i koden og se hvordan.

2. En farverig type

Lad os forestille os, at vi har en simpel klasse, der repræsenterer en RGB-farve:

klasse CustomColor (val rgb: Int): Sammenlignelig {} 

Det ville være rart at kunne gentage sig over en række RGB-farver:

val a = CustomColor (0x000000) val b = CustomColor (0xCCCCCC) for (cc i a..b) {// gør ting}

3. Et hurtigt kig på IntRange

Kort fortalt, vi bliver nødt til at implementere Sammenlignelig, Iterabelog ClosedRange. Fra vores tidligere artikel ved vi allerede, at vi bliver nødt til at implementere Sammenlignelig.

Lad os dykke ned i de to andre grænseflader IntRange klassedeklaration for nogle tip:

offentlig klasse IntRange (start: Int, endInclusive: Int): IntProgression (start, endInclusive, 1), ClosedRange 

Og så, IntrogressionErklæring viser, at den gennemføres Iterabel:

offentlig åben klasse IntProgression: Iterabel

Så vi vil gerne gøre noget lignende for at få dette til at fungere.

4. ColorRange Klasse

Synes godt om IntRange, lad os oprette en ColorRange klasse.

Til vores formål springer vi over at efterligne Introgression, også siden vi er okay med at have et standardtrin på 1. Dette vil forenkle tingene lidt og give os mulighed for simpelthen implementere begge dele ClosedRange og Iterabel direkte:

klasse ColorRange (tilsidesætte val start: CustomColor, tilsidesætte val endInclusive: CustomColor): ClosedRange, Iterable {tilsidesætte fun iterator (): Iterator {return ColorIterator (start, endInclusive)}}

Til vores implementering af iterator (), vi returnerer en ColorIterator klasse, der vil gøre det tunge løft ved faktisk at gå gennem området.

Fordi ColorRange implementerer ClosedRange interface, skal vi implementere sammenligne med metode til CustomColor klasse:

tilsidesætte sjov CompareTo (anden: CustomColor): Int {returner this.rgb.compareTo (other.rgb)}

5. ColorIterator Klasse

ColorIterator er det sidste stykke af puslespillet:

klasse ColorIterator (val start: CustomColor, val endInclusive: CustomColor): Iterator {var initValue = start tilsidesættelse fun hasNext (): Boolsk {return initValue <= endInclusive} tilsidesættelse sjov næste (): CustomColor {return initValue ++}}

Noter det initVærdi er af typen CustomColor. Så for at mutere det med ++ operatør, skal vi tilføje inc () metode til CustomColor såvel:

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

6. Brug af brugerdefineret rækkevidde

Vi er næsten der!

Da vi definerer vores brugerdefinerede sortiment, CustomColor klasse skal implementere rækkevidde til metode. Det rækkevidde til metode giver os mulighed for at gentage vores rækkevidde ved hjælp af .. operatør, ligesom hvordan tilføje inkl. moms giver os mulighed for at bruge ++ operatør.

Lad os tjekke det endelige produkt:

klasse CustomColor (val rgb: Int): Sammenlignelig {tilsidesætte fun comparTo (anden: CustomColor): Int {returnere this.rgb.compareTo (other.rgb)} operatør sjov rangeTo (at: CustomColor) = ColorRange (dette, at) operator fun inc (): CustomColor {returner CustomColor (rgb + 1)}}

Og det er alt, hvad vi har brug for!

Lad os endelig se, hvordan alt dette fungerer sammen, ved ved hjælp af en række af vores CustomColor klasse:

@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}}

I denne test har vi defineret en rækkevidde variabel og bruges til at gentage gennem CustomColor objekter samt omdanne det til en liste.

Lad os se et andet eksempel på brug af standarden indeholder metode på området:

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

7. Konklusion

Kotlin har en indfødt implementering af rækkevidde til Int, lang og Char værdier. I denne artikel lærte vi, hvordan man implementerer et interval på en tilpasset klasse.

Som altid er koden tilgængelig på GitHub.