Kotlin 1.7.0 est disponible et marque l'arrivée de la version Alpha du nouveau compilateur Kotlin/JVM K2,
stabilise les fonctionnalités du langage et apporte des améliorations de performances

Kotlin 1.7.0 est disponible. Cette mouture signe l'arrivée de la version Alpha du nouveau compilateur Kotlin/JVM K2, stabilise les fonctionnalités du langage et apporte des améliorations de performances pour les plateformes JVM, JS et Native.

Voici une liste des principales mises à jour de cette version :
  • Le nouveau compilateur Kotlin К2 est maintenant en Alpha et offre de sérieuses améliorations de performances. Il n'est disponible que pour la JVM et aucun des plugins du compilateur, y compris kapt, ne fonctionne avec.
  • Une nouvelle approche de la compilation incrémentale dans Gradle. La compilation incrémentielle est désormais également prise en charge pour les modifications apportées à l'intérieur des modules non-Kotlin dépendants et est compatible avec Gradle.
  • JetBrains a stabilisé les annotations d'exigence d'acceptation, les types définitivement non nullables et l'inférence du constructeur.
  • Il existe maintenant un opérateur de soulignement pour les arguments de type. Vous pouvez l'utiliser pour déduire automatiquement un type d'argument lorsque d'autres types sont spécifiés.
  • Cette version permet la mise en œuvre par délégation à une valeur en ligne d'une classe en ligne. Vous pouvez désormais créer des wrappers légers qui n'allouent pas de mémoire dans la plupart des cas.


Nouveau compilateur Kotlin K2 pour la JVM en Alpha

Cette version de Kotlin présente la version Alpha du nouveau compilateur Kotlin K2. Le nouveau compilateur vise à accélérer le développement de nouvelles fonctionnalités de langage, à unifier toutes les plateformes prises en charge par Kotlin, à apporter des améliorations de performances et à fournir une API pour les extensions de compilateur.

JetBrains indique qu'il est important de souligner qu'avec la version Alpha du nouveau compilateur K2, l'éditeur s'est principalement concentré sur l'amélioration des performances. C'est la raison pour laquelle, pour le moment, ce nouveau compilateur ne fonctionne qu'avec les projets JVM : il ne prend pas en charge Kotlin/JS, Kotlin/Native ou d'autres projets multiplateformes, et aucun des plugins de compilateur, y compris kapt, ne fonctionne avec lui.

Les benchmarks de JetBrains montrent des résultats remarquables sur ses projets internes :

Nom : un.png
Affichages : 53542
Taille : 15,6 Ko
Les chiffres de performance KLOC/s représentent le nombre de milliers de lignes de code que le compilateur traite par seconde.

Langage

Kotlin 1.7.0 introduit la prise en charge de l'implémentation par délégation et un nouvel opérateur de soulignement pour les arguments de type. Il stabilise également plusieurs fonctionnalités de langage introduites en tant que préversions dans les versions précédentes.

Autoriser l'implémentation par délégation à une valeur inline d'une classe inline

Si vous souhaitez créer un wrapper léger pour une instance de valeur ou de classe, il est nécessaire d'implémenter toutes les méthodes d'interface à la main. L'implémentation par délégation résout ce problème, mais elle ne fonctionnait pas avec les classes inline avant la version 1.7.0. Cette restriction a été supprimée, vous pouvez donc désormais créer des wrappers légers qui n'allouent pas de mémoire dans la plupart des cas.

Code kotlin : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
interface Bar {
    fun foo() = "foo"
}
 
@JvmInline
value class BarWrapper(val bar: Bar): Bar by bar
 
fun main() {
    val bw = BarWrapper(object: Bar {})
    println(bw.foo())
}

Opérateur de soulignement pour les arguments de type

Kotlin 1.7.0 introduit un opérateur de soulignement, _, pour les arguments de type. Vous pouvez l'utiliser pour déduire automatiquement un argument de type lorsque d'autres types sont spécifiés :

Code Kotlin : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
abstract class SomeClass<T> {
    abstract fun execute(): T
}
 
class SomeImplementation : SomeClass<String>() {
    override fun execute(): String = "Test"
}
 
class OtherImplementation : SomeClass<Int>() {
    override fun execute(): Int = 42
}
 
object Runner {
    inline fun <reified S: SomeClass<T>, T> run(): T {
        return S::class.java.getDeclaredConstructor().newInstance().execute()
    }
}
 
fun main() {
    // T is inferred as String because SomeImplementation derives from SomeClass<String>
    val s = Runner.run<SomeImplementation, _>()
    assert(s == "Test")
 
    // T is inferred as Int because OtherImplementation derives from SomeClass<Int>
    val n = Runner.run<OtherImplementation, _>()
    assert(n == 42)
}

Vous pouvez utiliser l'opérateur de soulignement à n'importe quelle position dans la liste des variables pour déduire un argument de type.

Inférence de constructeur stable

L'inférence de générateur est un type spécial d'inférence de type qui est utile lors de l'appel de fonctions de générateur 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.

À partir de la version 1.7.0, l'inférence de générateur 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, qui a été introduite dans la version 1.6.0.

Conditions d'adhésion (opt-in) stables

Les conditions d'adhésion sont désormais stables et ne nécessitent pas de configuration supplémentaire du compilateur.

Avant la version 1.7.0, la fonctionnalité opt-in elle-même nécessitait l'argument -opt-in=kotlin.RequiresOptIn pour éviter un avertissement. Cela n'est plus nécessaire ; cependant, vous pouvez toujours utiliser l'argument du compilateur -opt-in pour accepter d'autres annotations, module par module.

Types stables définitivement non nullables

Dans Kotlin 1.7.0, les types définitivement non nullables ont été promus à Stable. Ils offrent une meilleure interopérabilité lors de l'extension des classes et des interfaces Java génériques.

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 de la notation des types d'intersection et est maintenant limitée à un paramètre de type avec des bornes supérieures nullables sur le côté gauche de & et un Any non nullable sur le côté droit :

Code Kotlin : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
fun <T> elvisLike(x: T, y: T & Any): T & Any = x ?: y
 
fun main() {
    // OK
    elvisLike<String>("", "").length
    // Error: 'null' cannot be a value of a non-null type
    elvisLike<String>("", null).length
 
    // OK
    elvisLike<String?>(null, "").length
    // Error: 'null' cannot be a value of a non-null type
    elvisLike<String?>(null, null).length
}

Kotlin/JVM

Cette version apporte des améliorations de performances pour le compilateur Kotlin/JVM et une nouvelle option de compilateur. De plus, les références appelables aux constructeurs d'interfaces fonctionnelles sont devenues stables. Notez que depuis la 1.7.0, la version cible par défaut pour les compilations Kotlin/JVM est désormais la 1.8.

Optimisations des performances du compilateur

Kotlin 1.7.0 introduit des améliorations de performances pour le compilateur Kotlin/JVM. Selon les benchmarks de JetBrains, le temps de compilation a été réduit de 10% en moyenne par rapport à Kotlin 1.6.0. Les projets avec de nombreuses utilisations de fonctions en ligne, par exemple, les projets utilisant kotlinx.html, seront compilés plus rapidement grâce aux améliorations apportées au post-traitement du bytecode.

Nouvelle option du compilateur : -Xjdk-release

Kotlin 1.7.0 présente une nouvelle option de compilateur, -Xjdk-release. Cette option est similaire à l'option de ligne de commande --release de javac. L'option -Xjdk-release contrôle la version cible du bytecode et limite l'API du JDK dans le classpath à la version Java spécifiée. Par exemple, kotlinc -Xjdk-release=1.8 n'autorisera pas le référencement de java.lang.Module même si le JDK dans les dépendances est la version 9 ou supérieure.

Kotlin/natif

Kotlin 1.7.0 inclut des modifications de l'interopérabilité Objective-C et Swift et stabilise les fonctionnalités introduites dans les versions précédentes. Il apporte également des améliorations de performances pour le nouveau gestionnaire de mémoire ainsi que d'autres mises à jour.

Améliorations des performances pour le nouveau gestionnaire de mémoire

Le nouveau gestionnaire de mémoire est toujours en Alpha, mais il est en passe de devenir Stable. Cette version offre des améliorations de performances significatives pour le nouveau gestionnaire de mémoire, en particulier dans la récupération de place (GC). En particulier, l'implémentation simultanée de la phase de balayage, introduite dans la version 1.6.20, est désormais activée par défaut. Cela permet de réduire le temps de pause de l'application pour GC. Le nouveau planificateur GC est meilleur pour choisir la fréquence GC, en particulier pour les tas plus importants.

De plus, JetBrains a spécifiquement optimisé les binaires de débogage, en veillant à ce que le niveau d'optimisation et les optimisations de temps de liaison appropriés soient utilisés dans le code d'implémentation du gestionnaire de mémoire. Cela leur a permis d'améliorer le temps d'exécution d'environ 30 % pour les binaires de débogage sur nos benchmarks.

Plug-in de compilateur unifié ABI avec backends JVM et JS IR

À partir de Kotlin 1.7.0, le plug-in Kotlin Multiplatform Gradle utilise le fichier jar de compilateur intégrable pour Kotlin/Native par défaut. Cette fonctionnalité a été annoncée dans la version 1.6.0 comme expérimentale, et maintenant elle est stable et prête à l'emploi. Cette amélioration est très pratique pour les auteurs de bibliothèques, car elle améliore l'expérience de développement du plugin du compilateur. Avant cette version, vous deviez fournir des artefacts distincts pour Kotlin/Native, mais vous pouvez désormais utiliser les mêmes artefacts de plug-in de compilateur pour Native et les autres plateformes prises en charge.

Prise en charge des exécutables Android autonomes

Kotlin 1.7.0 fournit une prise en charge complète de la génération d'exécutables standard pour les cibles Android natives. Il a été introduit dans 1.6.20, et maintenant il est activé par défaut. Si vous souhaitez revenir au comportement précédent lorsque Kotlin/Native a généré des bibliothèques partagées, utilisez le paramètre suivant*:

Code Kotlin : Sélectionner tout - Visualiser dans une fenêtre à part
binaryOptions["androidProgramType"] = "nativeActivity"

Interopérabilité avec Swift async/wait*: renvoi de Void au lieu de KotlinUnit

Les fonctions suspend de Kotlin renvoient désormais le type Void au lieu de KotlinUnit dans Swift. Ceci est le résultat de l'amélioration de l'interopérabilité avec l'async/wait de Swift. Cette fonctionnalité a été introduite dans la version 1.6.20 et cette version active ce comportement par défaut.

Vous n'avez pas besoin d'utiliser la propriété kotlin.native.binary.unitSuspendFunctionObjCExport=proper pour retourner le type approprié pour de telles fonctions.

Exceptions non déclarées interdites via les ponts Objective-C

Lorsque vous appelez du code Kotlin à partir du code Swift/Objective-C (ou vice versa) et que ce code lève une exception, il doit être géré par le code où l'exception s'est produite, sauf si vous avez spécifiquement autorisé le transfert d'exceptions entre les langages avec une conversion appropriée (par exemple, en utilisant l'annotation @Throws).

Auparavant, Kotlin avait un autre comportement involontaire où des exceptions non déclarées pouvaient "fuir" d'un langage à un autre dans certains cas. Kotlin 1.7.0 corrige ce problème, et maintenant de tels cas conduisent à l'arrêt du programme.

Ainsi, par exemple, si vous avez un lambda { throw Exception() } dans Kotlin et que vous l'appelez depuis Swift, dans Kotlin 1.7.0, il se terminera dès que l'exception atteindra le code Swift. Dans les versions précédentes de Kotlin, une telle exception pouvait fuir vers le code Swift.

Intégration améliorée de CocoaPods

À partir de Kotlin 1.7.0, vous n'avez plus besoin d'installer le plugin Cocoapods-generate si vous souhaitez intégrer CocoaPods dans vos projets.

Auparavant, vous deviez installer à la fois le gestionnaire de dépendances CocoaPods et le plug-in de génération de cocoapods pour utiliser CocoaPods, par exemple, pour gérer les dépendances iOS dans les projets Kotlin Multiplatform Mobile.

Désormais, la configuration de l'intégration de CocoaPods est plus facile et JetBrains a résolu le problème où Cocoapods-generate ne pouvait pas être installé sur Ruby 3 et versions ultérieures. Désormais, les dernières versions de Ruby qui fonctionnent mieux sur Apple M1 sont également prises en charge.

Remplacement de l'URL de téléchargement du compilateur Kotlin/Native

À partir de Kotlin 1.7.0, vous pouvez personnaliser l'URL de téléchargement du compilateur Kotlin/Native. Ceci est utile lorsque les liens externes sur le CI sont interdits. Pour remplacer l'URL de base par défaut https://download.jetbrains.com/kotlin/native/builds, utilisez la propriété Gradle suivante*:

Code Kotlin : Sélectionner tout - Visualiser dans une fenêtre à part
kotlin.native.distribution.baseDownloadUrl=https://example.com

En savoir plus sur Kotlin 1.7.0