Fonctions de portée — ce qu'elles sont, types et utilisation dans Kotlin

Auteur : IT Sectr Publié le : 2026-06-23 Temps de lecture : 8 min

Les fonctions de portée dans Kotlin sont cinq fonctions de la bibliothèque standard (let, run, with, apply, also) qui exécutent un bloc de code dans le contexte d'un objet. Elles diffèrent par la façon d'accéder à l'objet (via it ou this) et la valeur de retour (objet de contexte ou résultat de la lambda). Selon la documentation Kotlin (2026), le bon choix de fonction de portée réduit le code passe-partout de 25 à 40 %. Les fonctions de portée aident à écrire l'initialisation, la configuration et les transformations d'objets dans un style déclaratif.

Points clés

  • Fonctions de portée — cinq fonctions Kotlin (let, run, with, apply, also) pour travailler dans le contexte d'un objet
  • Contexte via this — run, with, apply utilisent this, permettant d'appeler directement les méthodes de l'objet
  • Contexte via it — let et also passent l'objet comme paramètre it avec un nom explicite
  • Retour de l'objet — apply et also retournent l'objet de contexte pour chaîner les appels
  • Retour du résultat — let, run et with retournent la dernière expression de la lambda

Que sont les fonctions de portée ?

Les fonctions de portée sont un ensemble de cinq fonctions (let, run, with, apply, also) intégrées à la bibliothèque standard de Kotlin. Chacune d'elles prend une lambda et modifie temporairement la portée afin que le code à l'intérieur de la lambda s'exécute dans le contexte d'un objet spécifique. Cela évite de répéter le nom de l'objet pour plusieurs appels et regroupe les opérations connexes dans un seul bloc.

Deux caractéristiques clés distinguent les fonctions de portée : la façon d'accéder à l'objet de contexte (via this ou via it) et la valeur de retour (l'objet de contexte lui-même ou le résultat de la lambda). L'accès via this fait de l'objet un récepteur implicite — les méthodes et propriétés sont appelées sans préfixe. L'accès via it passe l'objet comme paramètre explicite de la lambda. Retourner l'objet permet le chaînage, retourner le résultat permet d'assigner la valeur transformée.

Historiquement, les fonctions de portée sont apparues comme un remplacement du modèle classique Builder et des variables temporaires pour l'initialisation. Au lieu de créer une classe builder séparée, le développeur écrit apply { propriété1 = ...; propriété2 = ... }. Cela réduit la quantité de code et rend l'initialisation plus lisible. Dans l'écosystème Kotlin, les fonctions de portée sont utilisées dans tous les frameworks et bibliothèques comme une idiome standard du langage.

Comparaison des fonctions de portée : this vs it, retour d'objet vs résultat

Le choix de la bonne fonction de portée est déterminé par deux questions : souhaitez-vous utiliser this ou it pour accéder à l'objet, et souhaitez-vous retourner l'objet lui-même ou le résultat de la lambda ? La combinaison de deux caractéristiques binaires donne quatre options possibles, et with occupe une place spéciale en tant que seule fonction qui n'est pas une extension.

FonctionAccèsRetourExtension ?Scénario typique
letitrésultat de la lambdaouiTransformation, vérification null
runthisrésultat de la lambdaouiCalcul avec contexte
withthisrésultat de la lambdanonRegroupement d'appels
applythisobjet de contexteouiInitialisation de propriétés
alsoitobjet de contexteouiEffets secondaires, journalisation

Pour configurer un objet sans retourner de nouvelle valeur, utilisez apply (accès via this) ou also (accès via it). Pour calculer une nouvelle valeur basée sur un objet, utilisez let (accès via it) ou run (accès via this). Pour regrouper des appels sans chaînage, utilisez with. Suivre ce schéma rend le code prévisible pour les autres développeurs familiers avec Kotlin.

apply et also : configuration avec retour d'objet

apply est une fonction de portée qui retourne l'objet de contexte et fournit un accès à celui-ci via this. C'est l'outil idéal pour initialiser les propriétés d'un objet après sa création. À l'intérieur du bloc apply, les propriétés peuvent être définies sans répéter le nom de l'objet. La méthode retourne l'objet lui-même, ce qui permet d'intégrer apply dans des chaînes ou de l'utiliser dans des initialiseurs.

kotlin
data class ServerConfig(
    var host: String = "localhost",
    var port: Int = 8080,
    var useTls: Boolean = false
)

val config = ServerConfig().apply {
    host = "api.example.com"
    port = 443
    useTls = true
}

Dans l'exemple, apply configure ServerConfig en accédant directement aux propriétés via this (this est omis). Sans apply, il faudrait écrire config.host = ..., config.port = ... — trois références répétitives à la même variable. Le retour de l'objet permet de sauvegarder le résultat de la configuration dans val config. also, contrairement à apply, passe l'objet via it et convient aux effets secondaires.

kotlin
fun saveUser(user: User) {
    validate(user).also { result ->
        println("Résultat de validation : $result")
    }
    val savedUser = user.also {
        log("Saving user ${it.id}")
        database.save(it)
    }
}

Dans l'exemple, also est utilisé pour la journalisation — tout en retournant l'objet original, il effectue un effet secondaire (affichage d'un message) sans modifier l'objet. C'est une chaîne : validate(user) retourne User, also journalise le résultat et transmet l'utilisateur. also est également utile pour ajouter des éléments à des collections ou pour déboguer au milieu d'une chaîne de transformations.

let et run : transformations et calculs

let est une fonction de portée qui retourne le résultat de la lambda et passe le contexte via it. C'est la fonction principale pour les transformations null-safe : si l'objet est nullable, la combinaison ?.let { } n'exécute le bloc que pour les valeurs non nulles. let est également utilisé pour limiter la portée des variables temporaires et pour les transformations de type map d'un type à un autre.

kotlin
fun findUser(id: Int): User?

val displayName = findUser(42)?.let { user ->
    "${user.name} (${user.email})"
} ?: "Unknown user"

// let avec transformation de collection
val numbers = listOf("1", "2", "3")
val parsed = numbers.firstOrNull()?.let {
    it.toIntOrNull()
} ?: 0

Dans le premier exemple, let est appelé via ?. — le bloc n'est exécuté que si findUser a retourné une valeur non nulle. La lambda prend user via it (peut être renommé pour plus de clarté) et retourne une chaîne formatée. Si l'utilisateur n'est pas trouvé, l'opérateur Elvis ?: fournit une valeur par défaut. Dans le deuxième exemple, let convertit une chaîne en nombre avec un null potentiel.

run est un analogue de let avec accès via this, retournant le résultat de la lambda. run est pratique pour les calculs qui nécessitent un contexte d'objet mais retournent une nouvelle valeur. Appeler run() sans objet (comme run { ... }) crée une portée temporaire pour les variables. with est une non-extension avec accès via this, adaptée au regroupement d'appels sans chaînage.

kotlin
// run comme calcul contextuel
val transformed = listOf(1, 2, 3).run {
    filter { it > 1 }.map { it * 10 }
}
println(transformed) // [20, 30]

// with pour regrouper les appels
val info = with(StringBuilder()) {
    append("Name: ")
    append("Alice")
    toString()
}

Dans l'exemple, run sur une liste retourne le résultat du filtrage et du mapping — la transformation elle-même, pas la liste. with prend StringBuilder comme argument (pas via un point) et travaille à l'intérieur avec this : append, append, toString. Le résultat de with est la chaîne info. Le choix entre run et with est souvent subjectif, mais with est préférable lorsque l'objet est passé d'un autre endroit sans chaînage.

with : contexte sans extension

with diffère des autres fonctions de portée en ce qu'elle n'est pas une fonction d'extension. Elle prend l'objet comme premier argument et la lambda comme second. À l'intérieur de la lambda, l'objet est accessible via this. with est pratique pour regrouper des appels de méthodes d'objet sans sauvegarder le résultat ou lorsque vous avez besoin d'« entrer » temporairement dans un contexte pour lire plusieurs propriétés.

kotlin
val user = User("Alice", "alice@example.com", "Admin")

val summary = with(user) {
    "User $name has role $role and email $email"
}
println(summary)

// with pour l'initialisation de composants UI
with(TextView(context)) {
    text = "Hello"
    textSize = 18.0f
    setTextColor(Color.BLUE)
}

Dans le premier exemple, with forme la chaîne summary en accédant directement aux propriétés de user via this. Sans with, il faudrait écrire « User ${user.name} has role ${user.role} » — répétition de user. Dans le deuxième exemple, with regroupe la configuration de TextView : toutes les méthodes et propriétés sont appelées sur un seul objet sans répétition. Inconvénient de with — impossibilité de l'utiliser dans une chaîne, car ce n'est pas une extension et elle ne retourne pas l'objet de contexte.

Questions fréquentes

Quelle fonction de portée choisir pour initialiser un objet ?

Utilisez apply — il retourne l'objet et fournit un accès via this, permettant de définir les propriétés sans répéter le nom de l'objet. also convient si vous avez besoin d'un paramètre it explicite pour le distinguer des propriétés de l'objet.

En quoi let diffère-t-il de run ?

let passe le contexte via it (paramètre explicite), run — via this (récepteur implicite). let est pratique pour les vérifications null et les transformations, run — pour les calculs avec contexte. Les deux retournent le résultat de la lambda.

Quand utiliser with au lieu de apply ?

with n'est pas une extension — elle prend l'objet comme argument. Utilisez with pour regrouper des appels lorsque le chaînage n'est pas nécessaire. apply est une extension qui retourne l'objet, pratique dans les initialiseurs et les modèles builder.

Peut-on imbriquer une fonction de portée dans une autre ?

Oui, mais soyez prudent avec this — this imbriqué crée de la confusion. Utilisez let ou also avec des noms explicites pour les contextes imbriqués afin d'éviter toute ambiguïté lors de la référence à l'objet externe.

Quelle fonction de portée est la plus performante ?

Toutes les fonctions de portée sont inline, donc elles ne créent pas de surcharge de classes anonymes. La différence de performance entre elles est négligeable. Le choix doit être basé sur la lisibilité et les conventions, pas sur la vitesse.

Résumé

  • Fonctions de portée — cinq fonctions inline de Kotlin (let, run, with, apply, also) pour exécuter du code dans le contexte d'un objet
  • apply retourne l'objet de contexte avec accès via this — idéal pour l'initialisation de propriétés
  • also retourne l'objet de contexte avec accès via it — adapté à la journalisation et aux effets secondaires
  • let retourne le résultat de la lambda avec accès via it — base des transformations null-safe
  • run retourne le résultat de la lambda avec accès via this — pratique pour les calculs avec contexte
  • with n'est pas une extension et retourne le résultat de la lambda — adaptée au regroupement d'appels sans chaînage
  • Combinaison de caractéristiques (this/it et retour d'objet/résultat) détermine le choix de la fonction de portée pour chaque tâche

Nous développerons une application mobile clé en main

IT Sectr crée des applications iOS et Android pour les startups et les entreprises depuis 2017. Nous vous conseillerons et vous proposerons la meilleure solution.

Discuter du projet

Lisez aussi