- Des changements apportés à l'inférence du constructeur.
- Le retour des fonctions de collection min() et max().
- La stabilisation des types définitivement non nullables.
- Des mises à jour pour le nouveau Kotlin/Native Memory Manager.
Avant d'aller plus loin, il peut être important de noter qu'à partir de la version 1.7.0, JetBrains met à jour un peu sa terminologie de versionnage en remplaçant le terme "Milestone" utilisé pour désigner les préversions par "Beta". Il y a quelques raisons qui justifient cette décision :
- JetBrains souhaite que la terminologie des builds Kotlin soit plus alignée sur la terminologie standard du cycle de publication du logiciel. Pour le dire plus précisément, "Bêta" signifie que JetBrains a fini d'ajouter de nouvelles fonctionnalités à cette version spécifique et que l'éditeur travaille sur la stabilisation. Cependant, des modifications finales seront mises en œuvre, y compris les modifications basées sur les retours des utilisateurs.
- Il y a quelque temps, les compilateurs M-release produisaient du code “pre-release”, ce qui rendait ces versions plus difficiles à tester. Ce n'est plus le cas. JetBrains veut éviter toute confusion et insiste sur le fait qu'essayer des versions bêta de Kotlin est un processus simple et fortement encouragé par l'équipe Kotlin.
- Enfin et surtout, le terme "Bêta" lui-même est un appel aux commentaires de la communauté. JetBrains l'utilise pour vous faire savoir qu'elle souhaite que vous lui fassiez part de vos commentaires.
Cela dit, quelles sont les nouveautés et améliorations qui arrivent dans la version 1.7.0 de Kotlin ?
Modifications apportées à l'inférence du constructeur
L'inférence du constructeur est un type spécial d'inférence de type qui est utile lors de l'appel de fonctions de constructeur génériques. Il aide le compilateur à déduire les arguments de type d'un appel en utilisant les informations de type sur les autres appels à l'intérieur de son argument lambda.
Kotlin 1.7.0-Beta inclut d'autres modifications de l'inférence du constructeur. Cela rapproche JetBrains de la stabilisation de l'inférence du constructeur et de l'achèvement de l'un des éléments de sa feuille de route.
Avec cette version, l'inférence du constructeur est automatiquement activée si une inférence de type standard ne peut pas obtenir suffisamment d'informations sur un type sans spécifier l'option de compilateur -Xenable-builder-inference, que JetBrains a introduite dans la version 1.6.0.
Cela signifie que vous pouvez désormais écrire vos propres constructeurs qui utilisent l'inférence de type de constructeur sans appliquer d'annotations ou d'options supplémentaires.
Le retour des fonctions de collection min() et max()
Dans Kotlin 1.4, JetBrains a renommé les fonctions de collection min() et max() en minOrNull() et maxOrNull(). Ces nouveaux noms reflètent mieux leur comportement - renvoyant null si la collection du récepteur est vide. Cela a également aidé à aligner le comportement des fonctions sur les conventions de nommage utilisées dans l'API des collections Kotlin.
Il en était de même pour minBy(), maxBy(), minWith() et maxWith(), qui ont tous obtenu leurs synonymes *OrNull() dans Kotlin 1.4. Les fonctions plus anciennes affectées par ce changement ont été progressivement rendues obsolètes.
Kotlin 1.7.0-Beta réintroduit les noms de fonction d'origine, mais avec un type de retour non nullable. Les nouveaux min(), max(), minBy(), maxBy(), minWith() et maxWith() renvoient désormais strictement l'élément de collection ou lèvent une exception.
Code : | Sélectionner tout |
1 2 3 4 5 6 | fun main() { val numbers = listOf<Int>() println(numbers.maxOrNull()) // "null" println(numbers.max()) // "Exception in… Collection is empty." } |
Stabilisation de types définitivement non nullables
Kotlin 1.7.0 aura des types définitivement non nullables stables, après leur introduction dans la version 1.6.20 du langage de programmation. Ces types ont été ajoutés pour fournir une meilleure interopérabilité lors de l'extension des classes et des interfaces Java génériques.
Depuis Kotlin 1.6.20, vous pouvez marquer un paramètre de type générique comme définitivement non nullable sur le site d'utilisation avec la nouvelle syntaxe T & Any. La forme syntaxique provient d'une notation des types d'intersection et est désormais limitée à un paramètre de type avec des bornes supérieures nullables à gauche de & et un Any non nullable à droite :
Code : | Sélectionner tout |
1 2 3 4 5 6 7 8 9 10 | fun <T> elvisLike(x: T, y: T & Any): T & Any = x ?: y fun main() { elvisLike<String>("", "").length // OK elvisLike<String>("", null).length // Error: 'null' cannot be a value of a non-null type elvisLike<String?>(null, "").length // OK elvisLike<String?>(null, null).length // Error: 'null' cannot be a value of a non-null type } |
Les types définitivement non nullables sont activés par défaut dans cette version bêta. Aucune étape supplémentaire n'est requise.
Correspondance avec Regex à une position particulière
Les fonctions Regex.matchAt() et Regex.matchesAt(), introduites dans la version 1.5.30 de Kotlin, sont désormais stables. Elles fournissent un moyen de vérifier si une expression régulière a une correspondance exacte à une position particulière dans une String ou une CharSequence.
matchesAt() recherche une correspondance et renvoie un résultat booléen :
Code : | Sélectionner tout |
1 2 3 4 5 6 7 8 9 | fun main(){ val releaseText = "Kotlin 1.7.0 is on its way!" // regular expression: one digit, dot, one digit, dot, one or more digits val versionRegex = "\\d[.]\\d[.]\\d+".toRegex() ​ println(versionRegex.matchesAt(releaseText, 0)) // "false" println(versionRegex.matchesAt(releaseText, 7)) // "true" } |
matchAt() renvoie la correspondance si elle est trouvée, ou null si elle ne l'est pas :
Code : | Sélectionner tout |
1 2 3 4 5 6 7 8 | fun main(){ val releaseText = "Kotlin 1.7.0 is on its way!" val versionRegex = "\\d[.]\\d[.]\\d+".toRegex() ​ println(versionRegex.matchAt(releaseText, 0)) // "null" println(versionRegex.matchAt(releaseText, 7)?.value) // "1.7.0" } |
Mises à jour du nouveau Kotlin/Native Memory Manager
Vous pouvez essayer la version Alpha du nouveau gestionnaire de mémoire de Kotlin/Native dans Kotlin 1.7.0-Beta. Cette version EAP apporte des améliorations de performances au nouveau gestionnaire de mémoire qui amélioreront l'expérience des développeurs.
Le nouveau gestionnaire de mémoire élimine les différences entre les plateformes JVM et Native. Il offre une expérience de développement cohérente dans les projets multiplateformes. Par exemple, vous aurez beaucoup plus de facilité à créer de nouvelles applications mobiles multiplateformes qui fonctionnent à la fois sur Android et iOS.
Le nouveau gestionnaire de mémoire Kotlin/Native lève les restrictions sur le partage d'objets entre les threads. Il fournit également des primitives de programmation simultanée sans fuite qui sont sûres et ne nécessitent aucune gestion ou annotation spéciale.
Le nouveau gestionnaire de mémoire deviendra celui par défaut dans les futures versions, JetBrains vous encourage donc à l'essayer maintenant.
Prise en charge des groupes de capture nommés dans JS et Native
Depuis Kotlin 1.7.0-Beta, les groupes de capture nommés sont pris en charge non seulement sur la JVM (1.8 et versions ultérieures), mais également dans JS et Native.
Pour donner un nom à un groupe de capture, utilisez la syntaxe (?<name>group) dans votre expression régulière. Pour obtenir le texte correspondant à un groupe, appelez la nouvelle fonction MatchGroupCollection.get() et transmettez le nom du groupe.
Récupérer la valeur de groupe correspondante par le nom
Considérez cet exemple pour faire correspondre les coordonnées d'une ville. Pour obtenir une collection de groupes correspondant à l'expression régulière, utilisez groups. Comparez la récupération du contenu d'un groupe par son numéro (index) et par son nom en utilisant value :
Code : | Sélectionner tout |
1 2 3 4 5 6 7 8 9 | fun main() { val regex = "\\b(?<city>[A-Za-z\\s]+),\\s(?<state>[A-Z]{2}):\\s(?<areaCode>[0-9]{3})\\b".toRegex() val input = "Coordinates: Austin, TX: 123" val match = regex.find(input)!! println(match.groups["city"]?.value) // "Austin" — by name println(match.groups[2]?.value) // "TX" — by number } |
Référence arrière nommée
Vous pouvez désormais également utiliser des noms de groupe lorsque vous faites référence arrière à des groupes. Les références arrière correspondent au même texte que celui précédemment mis en correspondance par un groupe de capture. Pour cela, utilisez la syntaxe \k<name> dans votre expression régulière :
Code : | Sélectionner tout |
1 2 3 4 5 6 7 | fun backRef() { val regex = "(?<title>\\w+), yes \\k<title>".toRegex() val match = regex.find("Do you copy? Sir, yes Sir!")!! println(match.value) // "Sir, yes Sir" println(match.groups["title"]?.value) // "Sir" } |
Groupes nommés dans des expressions de remplacement
Enfin, les références de groupe nommées peuvent être utilisées avec des expressions de remplacement. Considérez la fonction replace() qui substitue toutes les occurrences de l'expression régulière dans l'entrée par une expression de remplacement, et la fonction replaceFirst() qui remplace la première correspondance uniquement.
Les occurrences de ${name} dans la chaîne de remplacement sont remplacées par les sous-séquences correspondant aux groupes capturés avec le nom spécifié. Comparez les remplacements dans la référence de groupe par nom et par index:
Code : | Sélectionner tout |
1 2 3 4 5 6 7 | fun dateReplace() { val dateRegex = Regex("(?<dd>\\d{2})-(?<mm>\\d{2})-(?<yyyy>\\d{4})") val input = "Date of birth: 27-04-2022" println(dateRegex.replace(input, "\${yyyy}-\${mm}-\${dd}")) // "Date of birth: 2022-04-27" — by name println(dateRegex.replace(input, "\$3-\$2-\$1")) // "Date of birth: 2022-04-27" — by number } |
Comment essayer les nouvelles fonctionnalités de Kotlin 1.7.0
Vous pouvez facilement installer Kotlin 1.7.0-Beta dans votre EDI IntelliJ IDEA ou Android Studio. Notez qu'en raison du changement de nom des plugins Android Studio (bêta), l'installation du plugin est disponible pour les versions 1.6.20 et ultérieures.
Vous pouvez installer Kotlin 1.7.0-Beta de l'une des manières suivantes :
- Si vous utilisez le canal de mise à jour Early Access Preview (EAP), l'EDI vous proposera automatiquement la mise à jour vers la version 1.7.0-Beta dès qu'elle sera disponible.
- Si vous utilisez le canal de mise à jour stable, vous pouvez changer le canal en Early Access Preview à tout moment en sélectionnant Outils | Kotlin | Configurez les mises à jour du plugin Kotlin dans votre EDI. Vous pourrez alors installer la dernière préversion.
Vous pouvez toujours télécharger les dernières versions de ces EDI pour bénéficier d'une assistance étendue pour Kotlin :
- IntelliJ IDEA pour développer des applications Kotlin pour une variété de plateformes.
- Android Studio pour le développement d'applications mobiles Android et multiplateformes.
Une fois que vous avez installé la version 1.7.0-Beta, n'oubliez pas de changer la version de Kotlin en 1.7.0-Beta dans vos scripts de construction.
Installer le plugin Kotlin EAP pour IntelliJ IDEA ou Android Studio