Probeer met middelen in Kotlin

1. Inleiding

Beheerde talen, zoals talen die gericht zijn op de JVM, verwerken automatisch de meest voorkomende bron: geheugen.

We hebben echter te maken met allerlei soorten bronnen, niet alleen geheugen: bestanden, netwerkverbindingen, streams, vensters, enz. En, net als geheugen moeten deze worden vrijgegeven wanneer ze niet langer nodig zijn.

In dit artikel gaan we bekijken hoe bronnen automatisch kunnen worden beheerd in Kotlin en hoe het verschilt van Java's try-with-resources-constructie.

Als je de theorie wilt overslaan, ga dan direct naar het voorbeeld.

2. Automatisch bronnenbeheer

We kunnen drie verschillende fasen onderscheiden bij het werken met bronnen in Java (pseudocode):

resource = acquireresource () probeer {useResource (resource)} eindelijk {releaseResource (resource)} 

Als de taal of bibliotheek verantwoordelijk is voor het vrijgeven van de bron (het Tenslotte part), dan noemen we het Automatisch bronnenbeheer. Zo'n functie zorgt ervoor dat we niet hoeven te onthouden een bron vrij te maken.

Omdat resourcebeheer meestal aan een blokbereik is gekoppeld, worden deze, als we met meer dan één resource tegelijkertijd werken, altijd in de juiste volgorde vrijgegeven.

In Java implementeren objecten die een bron bevatten en in aanmerking komen voor automatisch bronbeheer een specifieke interface: Afsluitbaar voor I / O-gerelateerde bronnen en AutoCloseable.

Ook heeft Java 7 het reeds bestaande Afsluitbaar interface om uit te breiden AutoCloseable.

Daarom heeft Kotlin hetzelfde concept van resource-houders: dat wil zeggen, objecten die een van beide implementeren Afsluitbaar of AutoCloseable.

3. Het gebruik Functie in Kotlin

Om automatisch bronnen te beheren, hebben sommige talen een speciale constructie: Java 7 introduceerde bijvoorbeeld try-with-resources, terwijl C # de gebruik makend van trefwoord.

Soms bieden ze ons een patroon, zoals RAII in C ++. In sommige andere gevallen geven ze ons een bibliotheekmethode.

Kotlin valt in de laatste categorie.

Door het ontwerp heeft geen taalconstructie die lijkt op probeer-met-middelen in Java.

In plaats daarvan kunnen we een extensiemethode vinden met de naam gebruik in zijn standaardbibliotheek.

We zullen er later in detail naar kijken. Voorlopig moeten we gewoon weten dat elk resourceholder-object de gebruik methode die we kunnen aanroepen.

3.1. Hoe te gebruiken

Een simpel voorbeeld:

val writer = FileWriter ("test.txt") writer.use {writer.write ("iets")}

We kunnen een beroep doen op de gebruik functie op elk object dat implementeert AutoCloseable of Afsluitbaar, net als bij try-with-resources in Java.

De methode neemt een lambda-uitdrukking, voert deze uit en beschikt over de bron van (door dichtbij() erop) telkens wanneer de uitvoering het blok verlaat, normaal of met een uitzondering.

Dus in dit geval na gebruik, de auteur is niet meer bruikbaar, omdat Kotlin het automatisch heeft gesloten.

3.2. Een kortere vorm

In het bovenstaande voorbeeld hebben we voor de duidelijkheid een variabele gebruikt met de naam auteur, waardoor een sluiting ontstaat.

Echter, gebruik accepteert een lambda-expressie met een enkele parameterhet object met de bron:

FileWriter ("test.txt") .use {w -> w.write ("iets")}

Binnen het blok kunnen we ook de impliciete variabele gebruiken het:

FileWriter ("test.txt") .use {it.write ("something")}

Zoals we kunnen zien, hoeven we het object dus geen expliciete naam te geven. Het is echter meestal een goed idee om duidelijk te zijn in plaats van al te beknopte code te schrijven.

3.3. De definitie van gebruik()

Laten we eens kijken naar de definitie van gebruik functie in Kotlin, zoals gevonden in de standaardbibliotheek:

openbare inline fun T.use (blok: (T) -> R): R

We kunnen zien in de deel, dat gebruik wordt gedefinieerd als een extensiefunctie op Java's Afsluitbaar koppel.

Meer over extensiemethoden vindt u in ons inleidende artikel.

Natuurlijk is de gebruik functie is gedocumenteerd als onderdeel van de standaardbibliotheek van Kotlin.

3.4. Afsluitbaar vs AutoCloseable

Als we meer aandacht besteden aan het voorbeeld uit de vorige sectie, kunnen we zien dat de gebruik functiehandtekening is alleen gedefinieerd op de Afsluitbaar koppel. Dit komt doordat de standaardbibliotheek van Kotlin zich richt op Java 6.

In Java-versies vóór 7, AutoCloseable bestond niet en natuurlijk Afsluitbaar verlengde het niet.

In de praktijk zijn klassen die implementeren AutoCloseable maar niet Afsluitbaar zijn zeldzaam. Toch kunnen we er een tegenkomen.

In dat geval hoeven we alleen een afhankelijkheid toe te voegen aan de extensies van Kotlin voor Java 7, 8 of welke versie we ook targeten:

 org.jetbrains.kotlin kotlin-stdlib-jdk8 

De nieuwste versie van de afhankelijkheid is te vinden op Maven Central.

Dat geeft ons een andere gebruik extensie functie gedefinieerd op de AutoCloseable koppel:

openbaar inline plezier T.use (blok: (T) -> R): R

4. Conclusie

In deze tutorial hebben we gezien hoe een eenvoudige uitbreidingsfunctie in de standaardbibliotheek van Kotlin alles is wat we nodig hebben om alle soorten bronnen die bij de JVM bekend zijn automatisch te beheren.

De implementatie van al deze voorbeelden en codefragmenten is te vinden in het GitHub-project.