Try-with-Ressourcen in Kotlin

Versuchen Sie es mit Ressourcen in Kotlin

1. Einführung

Verwaltete Sprachen, z. B. für die JVM, verarbeiten automatisch die am häufigsten verwendete Ressource: Speicher.

Wir müssen uns jedoch mit allen Arten von Ressourcen befassen, nicht nur mit Speicher: Dateien, Netzwerkverbindungen, Streams, Fenstern usw. Undjust like memory, those need to be released when no longer needed.

In diesem Artikel wird untersucht, wie Ressourcen in Kotlin automatisch verwaltet werden können und wie sie sich vonJava’s try-with-resources constructunterscheiden.

Wenn Sie die Theorie überspringen möchten,jump straight to the example.

2. Automatische Ressourcenverwaltung

Wir können drei verschiedene Phasen bei der Arbeit mit Ressourcen in Java unterscheiden (Pseudocode):

resource = acquireResource()
try {
    useResource(resource)
} finally {
    releaseResource(resource)
}

Wenn die Sprache oder Bibliothek für die Freigabe der Ressource verantwortlich ist (der Teil vonfinally), nennen wir sieAutomatic Resource Management.. Solche Funktionrelieves us from having to remember to free a resource.

Da die Ressourcenverwaltung normalerweise an einen Blockbereich gebunden ist, werden sie immer in der richtigen Reihenfolge freigegeben, wenn wir mehr als eine Ressource gleichzeitig bearbeiten.

In Java implementieren Objekte, die eine Ressource enthalten und für die automatische Ressourcenverwaltung geeignet sind, eine bestimmte Schnittstelle:Closeable für E / A-bezogene Ressourcen undAutoCloseable.

Außerdem hat Java 7 die bereits vorhandeneCloseable-Schnittstelle nachgerüstet, umAutoCloseable zu erweitern.

Daher hat Kotlin das gleiche Konzept von Ressourceninhabern: dh Objekte, die entwederCloseable oderAutoCloseable implementieren.

3. Dieuse-Funktion in Kotlin

Um Ressourcen automatisch zu verwalten, haben einige Sprachen ein dediziertes Konstrukt: Java 7 hat beispielsweisetry-with-resources eingeführt, während C #the using keyword hat.

Manchmal bieten sie uns ein Muster wieRAII in C++ an. In einigen anderen Fällen geben sie uns eine Bibliotheksmethode.

Kotlin fällt in die letztere Kategorie.

Von Natur aus ist esdoesn’t have a language construct akin to try-with-resources in Java.

Stattdessen finden wir in der Standardbibliothek eine Erweiterungsmethode namensuse.

Wir werden uns das später genauer ansehen. Im Moment müssen wir nur wissen, dass jedes Ressourceninhaberobjekt die Methodeusehat, die wir aufrufen können.

3.1. Wie man es benutzt

Ein einfaches Beispiel:

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

Wir können die Funktionuse für jedes Objekt aufrufen, dasAutoCloseable oderCloseable implementiert, genau wie beim Versuch mit Ressourcen in Java.

Die Methode nimmt einen Lambda-Ausdruck, führt ihn aus und verfügt über die Ressource (durch Aufrufen vonclose()), wenn die Ausführung den Block entweder normal oder mit einer Ausnahme verlässt.

In diesem Fall istwriter nachuse, nicht mehr verwendbar, da Kotlin es automatisch geschlossen hat.

3.2. Eine kürzere Form

Im obigen Beispiel haben wir der Übersichtlichkeit halber eine Variable namenswriter verwendet, um einen Abschluss zu erstellen.

use akzeptiert jedoch einen Lambda-Ausdruck mit einem einzelnen Parameter das Objekt, das die Ressource enthält:

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

Innerhalb des Blocks können wir auch die implizite Variableit verwenden:

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

Wie wir sehen können, müssen wir dem Objekt keinen expliziten Namen geben. Es ist jedoch in der Regel eine gute Idee, klar zu sein, anstatt zu kurzen Code zu schreiben.

3.3. Die Definition vonuse()

Schauen wir uns die Definition deruse-Funktion in Kotlin an, wie sie in der Standardbibliothek zu finden ist:

public inline fun  T.use(block: (T) -> R): R

Wir können im<T : Closeable?, R>-Teil sehen, dassuse is defined as an extension function on Java’s Closeable interface.

Weitere Informationen zu Erweiterungsmethoden finden Sie inour introductory article.

Natürlich istthe use function is documentedTeil der Kotlin-Standardbibliothek.

3.4. Closeable vsAutoCloseable

Wenn wir das Beispiel aus dem vorherigen Abschnitt genauer betrachten, können wir sehen, dass die Funktionssignatur vonusenur auf der Schnittstelle vonCloseabledefiniert ist. This is because Kotlin’s standard library targets Java 6.

In Java-Versionen vor 7 warenAutoCloseable nicht vorhanden undCloseable haben sie natürlich nicht erweitert.

In der Praxis sind Klassen, dieAutoCloseable, aber nichtCloseable implementieren, selten. Trotzdem können wir auf einen von ihnen stoßen.

In diesem Fall müssen wir nur eine Abhängigkeit von Kotlins Erweiterungen für Java 7, 8 oder eine andere Version hinzufügen, auf die wir abzielen:


    org.jetbrains.kotlin
    kotlin-stdlib-jdk8

Die neueste Version der Abhängigkeit finden Sie inMaven Central.

Das gibt uns eine weitere Erweiterungsfunktion vonuse, die auf der Schnittstelle vonAutoCloseabledefiniert ist:

public inline fun  T.use(block: (T) -> R): R

4. Fazit

In diesem Tutorial haben wir gesehen, wie eine einfache Erweiterungsfunktion in Kotlins Standardbibliothek alles ist, was wir benötigen, um alle Arten von Ressourcen, die der JVM bekannt sind, automatisch zu verwalten.

Die Implementierung all dieser Beispiele und Codefragmente finden Sie inthe GitHub project - dies ist ein Maven-Projekt, daher sollte es einfach zu importieren und auszuführen sein.