ProgrammationDéveloppeur Backend

Décrivez le mécanisme des plages numériques en Kotlin : comment fonctionnent Range et Progression, comment créer vos propres plages et dans quels scénarios il est pratique de les utiliser ?

Réussissez les entretiens avec l'assistant IA Hintsage

Réponse

Historique de la question

Dès le début, Kotlin a introduit des plages (Range) pour simplifier les opérations sur des ensembles de valeurs consécutives - cela est hérité des langages avec une syntaxe concise pour travailler avec des nombres (par exemple, Python). De plus, le mécanisme Range a été étendu à Progression, permettant de définir un pas d'itération et de supporter différents types de nombres, de caractères.

Problème

L'itération sur des entiers, des lettres, des points temporels, etc., nécessite souvent une syntaxe particulière et un support solide dans la bibliothèque standard, sinon le code devient volumineux, illisible et sujet à des erreurs de limites.

Solution

Kotlin dispose de types standards IntRange, CharRange et LongRange, ainsi que de Progression pour l'itération par pas. De plus, il est possible de définir des plages pour des types comparables arbitraires.

// Plage simple for (i in 1..5) print(i) // 12345 // Plage avec pas for (i in 1..10 step 2) print(i) // 13579 // Plage inversée for (i in 5 downTo 1) print(i) // 54321 // Plage personnalisée (par exemple, pour Version) data class Version(val major: Int, val minor: Int): Comparable<Version> { override fun compareTo(other: Version): Int = compareValuesBy(this, other, Version::major, Version::minor) } operator fun ClosedRange<Version>.iterator(): Iterator<Version> = object : Iterator<Version> { var current = start override fun hasNext() = current <= endInclusive override fun next() = current.also { current = Version(current.major, current.minor + 1) } } val v1 = Version(1, 0) val v2 = Version(1, 3) for (v in v1..v2) println(v)

Caractéristiques clés :

  • Syntaxe standard des plages : .., downTo, until, step
  • Fonctionnement avec des types numériques, de caractères, et personnalisés
  • Utilisation dans des boucles, vérification d'appartenance, segmentation, validation

Questions piégeuses.

Quelle est la différence entre l'expression 1..5 et 1 until 5 ?

1..5 inclut les deux extrémités de la plage : 1,2,3,4,5. 1 until 5 n'inclut pas le dernier élément : 1,2,3,4.

Est-il possible de définir une plage avec un pas inférieur à zéro en utilisant step ?

Non. Pour des plages décroissantes, utilisez la construction downTo, puis step : 5 downTo 1 step 2 (vous obtenez 5,3,1).

Peut-on utiliser des plages avec des types ne réalisant pas Comparable ?

Non. Pour créer une plage, il est nécessaire que le type supporte la comparaison. Sinon, le compilateur n'autorise pas la définition.

Erreurs typiques et anti-patterns

  • Utilisation de until à la place de .. ou vice versa, confusion sur l'inclusion des limites
  • Définition d'un pas négatif pour une plage croissante (step ne rend pas la plage inverse)
  • Non respect des exigences Comparable pour les types personnalisés dans la plage

Exemple de la vie réelle

Cas négatif

Dans le code, au lieu de 1 until n+1, 1..n a été utilisé. On obtient un élément supplémentaire, la boucle dépasse la plage autorisée.

Avantages :

  • Cas limite capturé par inadvertance

Inconvénients :

  • Erreurs lors de la segmentation, calculs incorrects de sommes à la limite

Cas positif

Utilisation de for (i in 0 until n) pour l'indexation d'un tableau de longueur n, la plage correspond strictement aux valeurs d'index autorisées.

Avantages :

  • Erreurs de dépassement de tableau évitées
  • Lisibilité améliorée

Inconvénients :

  • Nécessité de retenir la différence entre .. et until lors du passage entre les langages