Early Access Program

Publication de la version 1.5.0-RC de Kotlin : modifications dans les bibliothèques standard et de tests

La version Release Candidate de Kotlin 1.5.0 est disponible et comprend toutes les fonctionnalités prévues pour la version 1.5.0. finale ! De nouvelles fonctionnalités de langage, des mises à jour de stdlib, une bibliothèque de tests améliorée et bien d’autres changements. Les seuls modifications supplémentaires pour la version 1.5.0 finale à venir seront des correctifs.

Essayez les API de Kotlin dans vos projets avec la version 1.5.0-RC et contribuez à peaufiner la version finale ! Vous pouvez nous signaler tout problème via notre outil de suivi YouTrack.

Installer la version 1.5.0-RC

Dans cet article, nous vous présentons les modifications apportées aux bibliothèques standard et de tests de Kotlin dans la version 1.5.0-RC :

Lisez ce qui suit pour connaître tous les détails !

Types d’entiers non signés stables

La bibliothèque standard comprend l’API des entiers non signés, utile pour traiter les opérations sur les entiers non négatifs. Elle comprend :

  • Types de nombres non signés : UInt, ULong, UByte, UShort et fonctions associées telles que les conversions.
  • Types d’agrégats : tableaux, plages et progressions d’entiers non signés : UIntArray, UIntRange et conteneurs similaires pour d’autres types.

Les types d’entiers non signés sont disponibles en bêta depuis la version Kotlin 1.3. Nous classons maintenant les types et les opérations des entiers non signés comme stables, les rendant disponibles sans opt-in et utilisables en toute sécurité dans des projets réels.

Les nouvelles API stables sont :

  • Types d’entiers non signés
  • Plages et progressions des types d’entiers non signés
  • Fonctions qui opèrent avec des types d’entiers non signés

Les tableaux d’entiers non signés restent en bêta. Il en va de même pour les entiers non signés varargs qui sont supportés par des tableaux. Si vous souhaitez les utiliser dans votre code, vous pouvez le faire avec l’annotation @ExperimentalUnsignedTypes.

En savoir plus sur les entiers non signés dans Kotlin.

Extensions pour l’API java.nio.file.Path

Kotlin fournit maintenant un moyen d’utiliser l’entrée/sortie Java non bloquante moderne dans un style idiomatique Kotlin prêt à l’emploi via les fonctions d’extension pour java.nio.file.Path.

Voici un petit exemple :

Ces extensions ont été introduites en tant que fonctionnalité expérimentale dans Kotlin 1.4.20 et sont maintenant disponibles sans opt-in. Consultez le paquet kotlin.io.path pour la liste des fonctions que vous pouvez utiliser.

Les extensions existantes pour File API restent disponibles, vous êtes donc libre de choisir l’API que vous préférez.

API indépendante des paramètres de localisation pour les majuscules et les minuscules

Beaucoup d’entre vous sont familiers avec les fonctions stdlib permettant de changer la casse des chaînes et des caractères : toUpperCase(), toLowerCase(), toTitleCase(). Elles fonctionnent généralement bien, mais peuvent devenir un véritable casse-tête lorsqu’il s’agit de gérer différentes localisations de plateformes. Elles sont toutes sensibles aux paramètres de localisation, leur résultat peut donc varier en fonction de la localisation. Par exemple, que retourne "Kotlin".toUpperCase() ? « Bien évidemment KOTLIN », diriez-vous. Mais dans les paramètres régionaux turcs, le i majuscule est İ, donc le résultat est différent : KOTLİN.

Il existe désormais une nouvelle API indépendante des paramètres de localisation pour changer la casse des chaînes et des caractères : les extensions uppercase(), lowercase(), titlecase(), et leurs équivalents *Char() Vous l’avez peut-être déjà essayée en avant-première dans la version 1.4.30.

Les nouvelles fonctions agissent de la même manière, quels que soient les paramètres de localisation de la plateforme. Appelez simplement ces fonctions et laissez le reste à la stdlib.

Les nouvelles fonctions agissent de la même manière, quels que soient les paramètres de localisation de la plateforme. Appelez simplement ces fonctions et laissez le reste à la stdlib.

Sur la JVM, vous pouvez effectuer un changement de casse sensible à la localisation en appelant les nouvelles fonctions avec la localisation actuelle comme argument :

Les nouvelles fonctions remplaceront complètement les anciennes, qui sont maintenant obsolètes.

Conversion claire des caractères en codes et des caractères en chiffres

L’opération permettant d’obtenir le code UTF-16 d’un caractère, la fonction toInt(), constituait un piège courant car sur des chaînes à un chiffre elle ressemble assez à String.toInt() qui produit un Int présenté par ce chiffre.

De plus, il n’existait pas de fonction générale permettant de renvoyer la valeur numérique 4 pour Char '4'.

Pour résoudre ces problèmes, il existe désormais un ensemble de nouvelles fonctions de conversion entre les caractères et leurs codes entiers et valeurs numériques :

  • Char(code) et Char.code effectuent la conversion ente un caractère et son code.
  • Char.digitToInt(radix: Int) et sa version *OrNull créent un entier à partir d’un chiffre dans la base spécifiée.
  • Int.digitToChar(radix: Int) crée un caractère à partir d’un chiffre qui représente un entier dans la base spécifiée.

Ces fonctions ont des noms clairs et rendent le code plus lisible :

Les nouvelles fonctions était disponibles en avant-première depuis Kotlin 1.4.30 et sont maintenant stables. Les anciennes fonctions de conversion de caractères en nombres (Char.toInt() et fonctions similaires pour les autres types numériques) et de conversion de nombres en caractères (Long.toChar() et fonctions similaires sauf pour Int.toChar()) sont maintenant obsolètes.

API de caractères multiplateforme étendue

Nous continuons à étendre la partie multiplateforme de la bibliothèque standard afin de fournir toutes ses capacités au code commun du projet multiplateforme.

Nous avons rendu un certain nombre de fonctions Char disponibles sur toutes les plateformes et dans le code commun. Ces fonctions sont :

  • Char.isDigit(), Char.isLetter(), Char.isLetterOrDigit() qui vérifient si un caractère est une lettre ou un chiffre.
  • Char.isLowerCase(), Char.isUpperCase(), Char.isTitleCase() qui vérifient la casse d’un caractère.
  • Char.isDefined() qui vérifie si un caractère a une catégorie générale Unicode autre que Cn (non défini).
  • Char.isISOControl() qui vérifie si un caractère est un caractère de contrôle ISO, dont le code est compris dans les plages \u0000..\u001F ou \u007F..\u009F.

La propriété Char.category et son type de retour de classe enum CharCategory, qui indique la catégorie générale d’un caractère selon Unicode, sont désormais disponibles dans les projets multiplateformes.

Versions strictes de String?.toBoolean()

La fonction String?.toBoolean() de Kotlin est très utilisée pour créer des valeurs booléennes à partir de chaînes. Cela fonctionne assez simplement : c’est true sur une chaîne “true” quelle que soit sa casse et false sur toutes les autres chaînes, y compris null.

Si ce comportement semble naturel, il peut cacher des erreurs potentielles. Quoi que vous convertissiez avec cette fonction, vous obtenez un booléen même si la chaîne a une valeur inattendue.

De nouvelles versions strictes sensibles à la casse de String?.toBoolean() sont là pour éviter de telles erreurs :

  • String.toBooleanStrict() lance une exception pour toutes les entrées sauf les littéraux “true” et “false”.
  • String.toBooleanStrictOrNull() renvoie null pour toutes les entrées sauf les littéraux “true” et “false”.

Modifications dans l’API Duration

L’API expérimentale mesure de la durée et du temps est disponible dans la stdlib depuis la version 1.3.50. Elle fournit une API pour la mesure précise d’intervalles de temps.

L’une des principales classes de cette API est Duration. Elle représente la durée entre deux instants de temps. Dans la version 1.5.0, Duration fait l’objet de modifications importantes, tant au niveau de l’API que de la représentation interne.

Duration utilise désormais une valeur Long pour la représentation interne au lieu de Double. La plage de valeurs Long permet de représenter plus de cent ans avec une précision de l’ordre de la nanoseconde ou cent millions d’années avec une précision de l’ordre de la milliseconde. Cependant, les durées inférieures à la nanoseconde précédemment prises en charge ne sont plus disponibles.

Nous introduisons également de nouvelles propriétés pour récupérer une durée sous forme de valeur Long. Elles sont disponibles pour diverses unités de temps, notamment Duration.inWholeMinutes et Duration.inWholeSeconds. Ces fonctions viennent remplacer les propriétés basées sur Double, telles que Duration.inMinutes.

Il y a également un ensemble de nouvelles fonctions d’usine pour créer des instances Duration à partir de valeurs entières. Elles sont définies directement dans le type Duration et remplacent les anciennes propriétés d’extension des types numériques telles que Int.seconds.

Compte tenu de ces changements majeurs, l’ensemble de l’API de mesure de la durée et du temps reste expérimentale dans la version 1.5.0 et requiert un opt-in avec l’annotation @ExperimentalTime.

Essayez la nouvelle version et partagez vos commentaires sur notre outil de suivi, YouTrack.

Opérations mathématiques : division entière et opérateur mod

Dans Kotlin, l’opérateur division (/) sur les entiers représente la division tronquée, qui ne prend pas en compte la partie fractionnaire du résultat. En arithmétique modulaire, il existe également une alternative : la division entière qui arrondit le résultat par le bas (vers le plus petit entier), ce qui produit un résultat différent sur les nombres négatifs.

Auparavant, la division entière nécessitait une fonction personnalisée, comme :

Dans la version 1.5.0-RC, nous présentons la fonction floorDiv() qui effectue des divisions entières sur les entiers.

Dans la version 1.5.0, nous introduisons la nouvelle fonction mod(). Elle fonctionne maintenant exactement comme son nom l’indique : elle renvoie le modulo, qui est le reste de la division entière.

Cela diffère de l’opérateur rem() (ou %) de Kotlin. Le modulo est la différence entre a et a.floorDiv(b) * b. Le modulo non nul a toujours le même signe que b alors que a % b peut en avoir un différent. Cela peut être utile lors de I’ implémentation de listes cycliques par exemple :

Collections : firstNotNullOf() et firstNotNullOfOrNull()

L’API de collections de Kotlin couvre un ensemble d’opérations populaires sur les collections avec des fonctions intégrées. Pour les cas qui ne sont pas courants, vous combinez généralement les appels de ces fonctions. Cette méthode fonctionne, mais n’est pas toujours très élégante et peut causer une surcharge.

Par exemple, pour obtenir le premier résultat non nul d’une fonction de sélecteur sur les éléments de la collection, vous pouvez appeler mapNotNull() et first(). Dans la version 1.5.0, vous pouvez le faire avec un seul appel d’une nouvelle fonction firstNotNullOf(). Avec firstNotNullOf(), nous ajoutons sa contrepartie *orNull() qui produit null s’il n’y a pas de valeur à retourner.

Voici un exemple montrant comment raccourcir votre code avec ces fonctions.

Supposons que vous ayez une classe avec une propriété de valeur null et que vous ayez besoin de sa première valeur non null dans une liste d’instances de classe.

You can implement this by iterating the collection and checking if a property is not null:

Il est également possible d’utiliser les fonctions précédemment existantes mapNotNull() et firstOrNull(). Notez que mapNotNull() construit une collection intermédiaire, ce qui nécessite de la mémoire supplémentaire, surtout pour les grandes collections. Ainsi, une transformation en une séquence peut également être nécessaire ici.

Voici le résultat avec la nouvelle fonction :

Modifications dans la bibliothèque de tests

Nous n’avions pas fourni de mises à jour majeures de la bibliothèque de tests Kotlin kotlin-test depuis plusieurs versions, mais nous apportons aujourd’hui des modifications très attendues. Avec la version 1.5.0-RC, vous pouvez essayer plusieurs nouvelles fonctionnalités :

  • Dépendance kotlin-test unique dans les projets multiplateformes.
  • Choix automatique d’un framework de test pour les ensembles de sources Kotlin/JVM.
  • Mises à jour des fonctions d’assertion.

Dépendance kotlin-test dans les projets multiplateformes

Nous poursuivons le développement du processus de configuration pour les projets multiplateformes. Dans la version 1.5.0, la mise en place d’une dépendance sur kotlin-test pour tous les ensembles de sources est facilitée.

Désormais, la dépendance kotlin-test dans l’ensemble de sources de tests commun est la seule que vous ayez à ajouter. Le plugin Gradle déduira la dépendance de la plateforme correspondante pour les autres ensembles de sources :

  • kotlin-test-junit pour les ensembles de sources JVM. Vous pouvez également passer à kotlin-test-junit-5 ou kotlin-test-testng si vous les activez explicitement (consultez la suite pour savoir comment).
  • kotlin-test-js pour les ensembles de sources Kotlin/JS.
  • kotlin-test-common et kotlin-test-annotations-common pour les ensembles de sources communs.
  • Aucun artefact supplémentaire pour les ensembles de sources Kotlin/Native car Kotlin/Native fournit des implémentations intégrées de l’API kotlin-test.

Choix automatique d’un framework de test pour les ensembles de sources Kotlin/JVM

Une fois que vous avez spécifié la dépendance kotlin-test dans l’ensemble de sources de tests commun tel que décrit ci-dessus, les jeux de sources JVM reçoivent automatiquement la dépendance sur JUnit 4. C’est tout ! Vous pouvez écrire et exécuter des tests immédiatement !

Voici ce que cela donne dans le DSL Groovy :

Et dans le DSL Kotlin :

Vous pouvez également passer à JUnit 5 ou TestNG en appelant simplement une fonction dans la tâche de test : useJUnitPlatform() ou useTestNG().

Il en va de même dans les projets limités à JVM lorsque vous ajoutez la dépendance kotlin-test.

Mises à jour des fonctions d’assertion

La version 1.5.0 apportera plusieurs nouvelles fonctions d’assertion, ainsi que des améliorations des fonctions existantes.

Passons d’abord rapidement en revue les nouvelles fonctions :

  • assertIs<T>() et assertIsNot<T>() vérifient le type de la valeur.
  • assertContentEquals() compare le contenu du conteneur pour les tableaux, les séquences et tout Iterable. Plus précisément, elle vérifie si expected et actual contiennent les mêmes éléments dans le même ordre.
  • assertEquals() et assertNotEquals() pour Double et Float ont de nouvelles surcharges avec un troisième paramètre : la précision.
  • assertContains() vérifie la présence d’un élément dans tout objet dont l’opérateur contains() est défini : tableau, liste, plage, et ainsi de suite.

Voici un bref exemple qui illustre l’utilisation de ces fonctions :

En ce qui concerne les fonctions d’assertion existantes, il est maintenant possible d’appeler des suspending functions au sein du lambda passé à assertTrue(), assertFalse(), et expect() car ces fonctions sont maintenant inline.

Essayer les nouvelles fonctionnalités de Kotlin 1.5.0

Utilisez toutes ces API Kotlin modernes pour vos projets en cours avec la version 1.5.0-RC !

Dans IntelliJ IDEA ou Android Studio, installez le plugin Kotlin 1.5.0-RC. Découvrez comment obtenir les versions du plugin EAP.

Construisez vos projets avec 1.5.0-RC pour voir comment ils fonctionneront avec 1.5.0. Avec la nouvelle configuration simplifiée pour les versions preview, il vous suffit de changer la version de Kotlin en 1.5.0-RC et d’ajuster les versions des dépendances si nécessaire.

Installer la version 1.5.0-RC

Comme toujours, vous pouvez essayer la dernière version en ligne sur Kotlin Playground.

Compatibilité

Comme pour toutes les versions majeures, certains cycles d’obsolescence de modifications précédemment annoncées arrivent à leur terme avec Kotlin 1.5.0. Tous ces cas ont été soigneusement examinés par le comité du langage et sont listés dans le Guide de compatibilité pour Kotlin 1.5. Vous pouvez également en savoir plus sur ces changements sur YouTrack.

Notes concernant la version Release Candidate

Maintenant que nous en sommes à la version release candidate de Kotlin 1.5.0, il est temps pour vous de commencer à compiler et à publier ! Contrairement aux versions précédentes, il est garanti que les binaires créés avec Kotlin 1.5.0-RC sont compatibles avec Kotlin 1.5.0.

Faites-nous part de vos commentaires

C’est la dernière occasion pour vous de contribuer à la prochaine version majeure ! Partagez tout problème que vous rencontrez sur notre outil de suivi. Aidez-nous à améliorer Kotlin 1.5.0, pour vous et pour la communauté !

Installer la version 1.5.0-RC

Auteur de l’article original en anglais : Pavel Semyonov