Inline klasser i Kotlin

1. Oversigt

I Kotlin 1.3+ har vi en eksperimentel ny type klasse, kaldet inline class. I denne vejledning fokuserer vi på brugen af ​​inline-klasser og også nogle af deres begrænsninger.

2. Opsætning

Som vi nævnte før, er inline-klasser et eksperimentelt træk ved Kotlin. Som en konsekvens vil compileren kaste et advarsel angiver den eksperimentelle status for funktionen.

For at undgå denne advarsel kan vi tilføje følgende Maven-kompilatorindstilling til vores konfiguration:

  -XXLanguage: + InlineClasses 

3. Hvad er inline-klasser?

Inline-klasser giver os en måde at pakke en type på, hvilket tilføjer funktionalitet og opretter en ny type i sig selv.

I modsætning til almindelige (ikke-inline) indpakninger, vil de drage fordel af forbedret ydeevne. Dette sker, fordi dataene er integreret i dets anvendelser, og objekt-instantiering springes over i den resulterende kompilerede kode.

Lad os se et eksempel på en inline-klasse kaldet InlinedCircleRadius med en egenskab af typen Dobbelt repræsenterer radius:

val circleRadius = InlinedCircleRadius (5.5)

For JVM er vores kode faktisk bare:

val cirkelradius = 5,5

Bemærk hvordan vores InlinedCircleRadius er ikke instantieret i den kompilerede kode, fordi den underliggende værdi er angivet, hvilket frigør os fra de præstationsstraffe, der er forbundet med instantiering.

3.1. Brugseksempel

Nu hvor vi ved, hvad inline-klasser er, diskuterer vi deres anvendelse.

En enkelt ejendom initialiseret i den primære konstruktør er det grundlæggende krav til eninline klasse. Den enkelte egenskab repræsenterer klasseinstansen ved kørsel.

Derfor kan vi bruge en enkelt kodelinje for at få en korrekt definition:

inline klasse InlineDoubleWrapper (val doubleValue: Double)

Vi definerede InlineDoubleWrapper som en simpel indpakning over en Dobbelt objekt og anvendte inline nøgleord til det. Endelig kan vi nu bruge denne klasse i vores kode uden yderligere ændringer:

@Test sjovt nårInclineClassIsUsed_ThenPropertyIsReadCorrectly () {val piDoubleValue = InlineDoubleWrapper (3.14) assertEquals (3.14, piDoubleValue.doubleValue)}

4. Klassemedlemmer

Indtil nu brugte vi inline-klasser ligesom enkle indpakninger. Men de er så meget mere end det. De giver os også mulighed for at definere egenskaber og funktioner ligesom almindelige klasser. Dette næste eksempel definerer en egenskab, der repræsenterer diameteren og en funktion til at returnere cirkelområdet:

inline klasse CircleRadius (privat val cirkel Radius: Dobbelt) {val diameterOfCircle get () = 2 * cirkelRadius sjovt områdeOfCircle = 3,14 * cirkelRadius * cirkelRadius}

Vi opretter nu en test til vores diameterOfCircle ejendom. Det vil instantiere vores CircleRadius inline-klasse, og ring derefter til ejendommen:

@Test sjov givenRadius_ThenDiameterIsCorrectlyCalculated () {val radius = CircleRadius (5.0) assertEquals (10.0, radius.diameterOfCircle)}

Og her er en simpel test til areaOfCircle fungere:

@Test sjov givenRadius_ThenAreaIsCorrectlyCalculated () {val radius = CircleRadius (5.0) assertEquals (78.5, radius.areaOfCircle ())}

Der er dog nogle begrænsninger for, hvad vi kan og ikke kan definere inden for vores inline-klasser. Mens egenskaber og funktioner er tilladt, skal vi nævne det i det blokke, indre klasser og underlagsfelter er ikke.

5. Arv

Det er vigtigt at nævne det inline-klasser kan kun arve fra grænseflader, og da vi ikke kan have underklasser, inline-klasser er også effektivt endelige.

Givet en grænseflade Kan tegnes med en metode tegne(), implementerer vi denne metode i vores CircleRadius klasse:

interface Drawable {fun draw ()} inline class CircleRadius (private val circleRadius: Double): Drawable {val diameterOfCircle get () = 2 * circleRadius fun areaOfCircle () = 3.14 * circleRadius * circleRadius tilsidesættelse fun draw () {println ("Draw min cirkel ")}}

6. Konklusioner

I denne hurtige artikel udforskede vi inline-klasser i Kotlin. Derudover talte vi om arv og definitionen af ​​egenskaber og funktioner.

Som sædvanligt kan alle disse eksempler og uddrag findes på GitHub.


$config[zx-auto] not found$config[zx-overlay] not found