Inline lessen in Kotlin

1. Overzicht

In Kotlin 1.3+ hebben we een experimenteel nieuw type klas, genaamd inline-klas. In deze tutorial zullen we ons concentreren op het gebruik van inline klassen en ook op enkele van hun beperkingen.

2. Installatie

Zoals we eerder vermeldden, zijn inline lessen een experimentele functie van Kotlin. Als gevolg hiervan zal de compiler een waarschuwing geeft de experimentele status van de functie aan.

Om deze waarschuwing te vermijden, kunnen we de volgende Maven-compileroptie aan onze configuratie toevoegen:

  -XXLanguage: + InlineClasses 

3. Wat zijn inline lessen?

Inline klassen bieden ons een manier om een ​​type in te pakken, waardoor functionaliteit wordt toegevoegd en op zichzelf een nieuw type wordt gemaakt.

In tegenstelling tot gewone (niet-inline) wikkels, zullen ze profiteren van verbeterde prestaties. Dit gebeurt omdat de gegevens zijn geïntegreerd in het gebruik ervan, en object-instantiatie wordt overgeslagen in de resulterende gecompileerde code.

Laten we een voorbeeld bekijken van een inline-klasse met de naam InlinedCircleRadius met een eigenschap van het type Dubbele vertegenwoordigt de straal:

val circleRadius = InlinedCircleRadius (5.5)

Voor de JVM is onze code eigenlijk gewoon:

val circleRadius = 5.5

Merk op hoe onze InlinedCircleRadius wordt niet geïnstantieerd in de gecompileerde code omdat de onderliggende waarde inline is, wat ons verlost van de prestatieboetes die gepaard gaan met instantiatie.

3.1. Gebruiksvoorbeeld

Nu we weten wat inline klassen zijn, bespreken we het gebruik ervan.

Een enkele eigenschap die is geïnitialiseerd in de primaire constructor, is de basisvereiste van eeninline klasse. De enkele eigenschap vertegenwoordigt de klasse-instantie tijdens runtime.

Om een ​​correcte definitie te hebben, kunnen we daarom een ​​enkele regel code gebruiken:

inline klasse InlineDoubleWrapper (waarde doubleValue: Double)

We hebben gedefinieerd InlineDoubleWrapper als een simpele wikkel over een Dubbele object en paste het in lijn trefwoord eraan. Ten slotte kunnen we deze klasse nu zonder aanvullende wijzigingen in onze code gebruiken:

@Test leuk whenInclineClassIsUsed_ThenPropertyIsReadCorrectly () {val piDoubleValue = InlineDoubleWrapper (3.14) assertEquals (3.14, piDoubleValue.doubleValue)}

4. Klasleden

Tot nu toe gebruikten we inline klassen net als simpele wrappers. Maar ze zijn zoveel meer dan dat. Ze stellen ons ook in staat om eigenschappen en functies te definiëren, net als gewone klassen. Dit volgende voorbeeld definieert een eigenschap die de diameter weergeeft en een functie om de oppervlakte van de cirkel te retourneren:

inline klasse CircleRadius (privé val circleRadius: Double) {val diameterOfCircle get () = 2 * circleRadius fun areaOfCircle = 3.14 * circleRadius * circleRadius}

We gaan nu een test maken voor onze diameterOfCircle eigendom. Het zal onze instantiëren CircleRadius inline-klasse en roep vervolgens de eigenschap aan:

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

En hier is een eenvoudige test voor de areaOfCircle functie:

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

Er zijn echter enkele beperkingen aan wat we wel en niet kunnen definiëren binnen onze inline klassen. Hoewel eigenschappen en functies zijn toegestaan, moeten we dat vermelden in het blokken, innerlijke klassen en achtergrondvelden zijn dat niet.

5. Overerving

Het is belangrijk om dat te vermelden inline klassen kunnen alleen erven van interfaces, en aangezien we geen subklassen kunnen hebben, inline klassen zijn ook effectief definitief.

Gegeven een interface Tekenbaar met een methode trek(), zullen we deze methode implementeren in onze 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 override fun draw () {println ("Draw mijn kring ")}}

6. Conclusies

In dit korte artikel hebben we inline lessen in Kotlin onderzocht. Daarnaast hadden we het over overerving en de definitie van eigenschappen en functies.

Zoals gewoonlijk zijn al deze voorbeelden en fragmenten te vinden op GitHub.