Try-with-resources in Kotlin

Ressources d'essayage à Kotlin

1. introduction

Les langues gérées, telles que celles ciblant la machine virtuelle Java, gèrent automatiquement la ressource la plus courante: la mémoire.

Cependant, nous devons gérer toutes sortes de ressources, pas seulement la mémoire: fichiers, connexions réseau, flux, fenêtres, etc. Et,just like memory, those need to be released when no longer needed.

Dans cet article, nous allons voir comment les ressources peuvent être gérées automatiquement dans Kotlin et en quoi elles diffèrent deJava’s try-with-resources construct.

Si vous voulez sauter la théorie,jump straight to the example.

2. Gestion automatique des ressources

Nous pouvons distinguer trois phases différentes lorsque vous utilisez des ressources en Java (pseudocode):

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

Si le langage ou la bibliothèque est responsable de la libération de la ressource (la partiefinally), alors nous l'appelonsAutomatic Resource Management. Cette fonctionnalitérelieves us from having to remember to free a resource.

De plus, étant donné que la gestion des ressources est généralement liée à une portée de bloc, si nous traitons avec plusieurs ressources en même temps, elles seront toujours publiées dans le bon ordre.

En Java, les objets qui contiennent une ressource et sont éligibles pour la gestion automatique des ressources implémentent une interface spécifique:Closeable pour les ressources liées aux E / S etAutoCloseable.

De plus, Java 7 a mis à niveau l'interface préexistanteCloseable pour étendreAutoCloseable.

Par conséquent, Kotlin a le même concept de détenteurs de ressources: c'est-à-dire des objets implémentant soitCloseable, soitAutoCloseable.

3. La fonctionuse dans Kotlin

Pour gérer automatiquement les ressources, certains langages ont une construction dédiée: Java 7 a introduittry-with-resources, par exemple, tandis que C # athe using keyword.

Parfois, ils nous offrent un modèle, commeRAII in C++. Dans d'autres cas, ils nous donnent une méthode de bibliothèque.

Kotlin entre dans cette dernière catégorie.

De par sa conception, ildoesn’t have a language construct akin to try-with-resources in Java.

Au lieu de cela, nous pouvons trouver une méthode d'extension appeléeuse dans sa bibliothèque standard.

Nous l'examinerons en détail plus tard. Pour l'instant, nous avons juste besoin de savoir que chaque objet détenteur de ressources a la méthodeuse que nous pouvons appeler.

3.1. Comment l'utiliser

Un exemple simple:

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

Nous pouvons invoquer la fonctionuse sur n'importe quel objet qui implémenteAutoCloseable ouCloseable, tout comme avec try-with-resources en Java.

La méthode prend une expression lambda, l'exécute et supprime la ressource de (en appelantclose() dessus) chaque fois que l'exécution quitte le bloc, normalement ou avec une exception.

Donc, dans ce cas, aprèsuse,, lewriter n'est plus utilisable, car Kotlin l'a automatiquement fermé.

3.2. Une forme plus courte

Dans l'exemple ci-dessus, pour plus de clarté, nous avons utilisé une variable appeléewriter, créant ainsi une fermeture.

Cependant,use accepte une expression lambda avec un seul paramètre l'objet contenant la ressource:

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

À l'intérieur du bloc, nous pouvons également utiliser la variable impliciteit:

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

Ainsi, comme nous pouvons le voir, nous n’avons pas à donner à l’objet un nom explicite. Cependant, il est généralement préférable d’être clair au lieu d’écrire un code trop concis.

3.3. La définition deuse()

Regardons la définition de la fonctionuse dans Kotlin, telle qu'elle se trouve dans sa bibliothèque standard:

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

On peut voir, dans la partie<T : Closeable?, R>, queuse is defined as an extension function on Java’s Closeable interface.

Vous trouverez plus d'informations sur les méthodes d'extension dansour introductory article.

Bien sûr,the use function is documented fait partie de la bibliothèque standard de Kotlin.

3.4. Closeable contreAutoCloseable

Si nous prêtons plus d'attention à l'exemple de la section précédente, nous pouvons voir que la signature de la fonctionuse est définie uniquement sur l'interfaceCloseable. This is because Kotlin’s standard library targets Java 6.

Dans les versions Java antérieures à 7,AutoCloseable n’existait pas et, bien sûr,Closeable ne l’étendait pas.

En pratique, les classes qui implémententAutoCloseable mais pasCloseable sont rares. Pourtant, nous pouvons en rencontrer un.

Dans ce cas, nous n'avons qu'à ajouter une dépendance aux extensions de Kotlin pour Java 7, 8 ou quelle que soit la version que nous ciblons:


    org.jetbrains.kotlin
    kotlin-stdlib-jdk8

La dernière version de la dépendance peut être trouvée surMaven Central.

Cela nous donne une autre fonction d'extensionuse définie sur l'interfaceAutoCloseable:

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

4. Conclusion

Dans ce tutoriel, nous avons vu comment une simple fonction d'extension dans la bibliothèque standard de Kotlin est tout ce dont nous avons besoin pour gérer automatiquement toutes sortes de ressources connues de la JVM.

L'implémentation de tous ces exemples et extraits de code se trouve dansthe GitHub project - il s'agit d'un projet Maven, il devrait donc être facile à importer et à exécuter tel quel.