Ce document vise à définir l'ensemble des normes de codage Android de Google pour le langage de programmation Kotlin. Le code source Kotlin est considéré comme conforme à ces normes si, et seulement si, il respecte les règles décrites ci-dessous.
Comme dans d'autres guides de style de programmation, les sujets abordés ne portent pas seulement sur l'aspect esthétique de la mise en forme du code, mais également sur d'autres types de conventions ou de normes de codage. Cependant, ce document se concentre principalement sur la définition des règles strictes que nous appliquons partout, et évite de fournir des recommandations qui peuvent être mal implémentées (que ce soit par un humain ou un outil).
Dernière mise à jour : 06/09/2023
Fichiers sources
Tous les fichiers sources doivent être encodés en UTF-8.
Dénominations
Si un fichier source ne contient qu'une seule classe de niveau supérieur, le nom du fichier doit utiliser le nom sensible à la casse et se terminer par l'extension .kt
. Si un fichier source contient plusieurs déclarations de niveau supérieur, choisissez un nom décrivant le contenu du fichier, écrit en PascalCase (le camelCase est acceptable si le nom du fichier est au pluriel) et suivi par l'extension .kt
.
// MyClass.kt class MyClass { }
// Bar.kt class Bar { } fun Runnable.toBar(): Bar = // …
// Map.kt fun <T, O> Set<T>.map(func: (T) -> O): List<O> = // … fun <T, O> List<T>.map(func: (T) -> O): List<O> = // …
// extensions.kt fun MyClass.process() = // … fun MyResult.print() = // …
Caractères spéciaux
Espaces blancs
Hormis la séquence de caractères de fin de ligne, le caractère d'espace ASCII horizontal (0x20) est le seul caractère d'espace blanc trouvé dans le fichier source. Cela signifie que :
- tous les autres types d'espaces blancs dans les littéraux de chaîne et de caractère sont échappés ;
- les caractères de tabulation ne sont pas utilisés pour les retraits.
Séquences d'échappement spéciales
Pour les caractères pour lesquels il existe une séquence d'échappement spéciale (\b
, \n
, \r
, \t
, \'
, \"
, \\
et \$
), celle-ci doit être utilisée à la place du code Unicode correspondant (par exemple \u000a
).
Caractères non ASCII
Pour les autres caractères non ASCII, utilisez le caractère Unicode (par exemple, ∞
) ou la séquence d'échappement Unicode équivalente (par exemple, \u221e
).
Le choix dépend uniquement de ce qui rend le code plus facile à lire et à comprendre.
Les échappements Unicode sont déconseillés pour les caractères imprimables, quel que soit l'emplacement, et fortement déconseillés en dehors des littéraux de chaîne et des commentaires.
Exemple | Discussion |
---|---|
val unitAbbrev = "μs" |
Excellent : parfaitement clair même sans commentaire. |
val unitAbbrev = "\u03bcs" // μs |
Mauvais : il n'y a aucune raison d'utiliser une séquence d'échappement pour un caractère imprimable. |
val unitAbbrev = "\u03bcs" |
Mauvais : le lecteur n'a aucune idée de ce que c'est. |
return "\ufeff" + content |
Bon : utilisez des caractères d'échappement pour les caractères non imprimables et ajoutez des commentaires si nécessaire. |
Structure
Un fichier .kt
comprend les éléments suivants (dans l'ordre indiqué) :
- En-tête sur la licence et/ou les droits d'auteur (facultatif)
- Annotations au niveau du fichier
- Déclaration de package
- Instructions d'importation
- Déclarations de niveau supérieur
Une ligne vide sépare chacune de ces sections.
Droits d'auteur/Licence
Si le fichier contient un en-tête de droits d'auteur ou de licence, celui-ci doit être placé tout en haut du fichier dans un commentaire multiligne.
/* * Copyright 2017 Google, Inc. * * ... */
N'utilisez pas de commentaire sur une seule ligne ou KDoc.
/** * Copyright 2017 Google, Inc. * * ... */
// Copyright 2017 Google, Inc. // // ...
Annotations au niveau du fichier
Les annotations avec la cible d'utilisation "file" sont placées entre tout commentaire d'en-tête et la déclaration de package.
Déclaration de package
La déclaration de package n'est soumise à aucune limite de colonne et n'est jamais encapsulée.
Instructions d'importation
Les instructions d'importation des classes, des fonctions et des propriétés sont regroupées dans une liste unique dans l'ordre de tri des caractères ASCII.
Les importations de caractères génériques (quel que soit leur type) ne sont pas autorisées.
Tout comme les déclarations de package, les instructions d'importation ne sont pas soumises à une limite de colonne et ne sont jamais encapsulées.
Déclarations de niveau supérieur
Un fichier .kt
peut déclarer un ou plusieurs types, fonctions, propriétés ou alias de type de niveau supérieur.
Le contenu d'un fichier doit porter sur un seul sujet. Il peut s'agir, par exemple, d'un seul type public ou d'un ensemble de fonctions d'extension effectuant la même opération sur plusieurs types de récepteurs. Les déclarations portant sur des sujets différents doivent être placées dans des fichiers distincts, et les déclarations publiques dans le même fichier doivent être réduites au minimum.
Aucune restriction explicite n'est appliquée au nombre ou à l'ordre des contenus d'un fichier.
Les fichiers sources sont généralement lus de haut en bas, ce qui signifie que, d'une manière générale, l'ordre doit refléter le fait que les déclarations placées plus haut permettent de mieux comprendre les suivantes. Le contenu de chaque fichier peut être organisé différemment. De même, un fichier peut contenir 100 propriétés, un autre 10 fonctions et un autre une seule classe.
Ce qui est important, c'est que chaque fichier utilise un certain ordre logique, que son mainteneur pourrait expliquer, si on le lui demandait. Par exemple, les nouvelles fonctions ne sont pas simplement ajoutées à la fin du fichier, car cela donnerait un ordre chronologique selon la date d'ajout, qui n'est pas un ordre logique.
Ordre des membres de classe
L'ordre des membres d'une classe suit les mêmes règles que les déclarations de niveau supérieur.
Mise en forme
Accolades
Les accolades ne sont pas obligatoires pour les branches when
et les expressions if
qui n'ont pas plus d'une branche else
et ne contiennent qu'une seule ligne.
if (string.isEmpty()) return val result = if (string.isEmpty()) DEFAULT_VALUE else string when (value) { 0 -> return // … }
Elles sont nécessaires pour les instructions et expressions if
, for
, when
branch, do
et while
, même si le corps est vide ou qu'il ne contient qu'une seule instruction.
if (string.isEmpty()) return // WRONG! if (string.isEmpty()) { return // Okay } if (string.isEmpty()) return // WRONG else doLotsOfProcessingOn(string, otherParametersHere) if (string.isEmpty()) { return // Okay } else { doLotsOfProcessingOn(string, otherParametersHere) }
Blocs non vides
Les accolades suivent le style Kernighan et Ritchie ("crochets égyptiens") pour les blocs non vides et les éléments de type bloc :
- Pas de saut de ligne avant l'accolade.
- Saut de ligne après l'accolade ouvrante.
- Saut de ligne avant l'accolade fermante.
- Saut de ligne après l'accolade fermante uniquement si elle termine une instruction ou le corps d'une fonction, d'un constructeur ou d'une classe nommée.
Par exemple, il n'y a pas de saut de ligne après l'accolade si elle est suivie d'une virgule ou de
else
.
return Runnable { while (condition()) { foo() } } return object : MyClass() { override fun foo() { if (condition()) { try { something() } catch (e: ProblemException) { recover() } } else if (otherCondition()) { somethingElse() } else { lastThing() } } }
Vous trouverez ci-dessous quelques exceptions pour les classes d'énumération.
Blocs vides
Un bloc vide ou un élément de type bloc doit être de style K&R.
try { doSomething() } catch (e: Exception) {} // WRONG!
try { doSomething() } catch (e: Exception) { } // Okay
Expressions
Un bloc conditionnel if/else
utilisé en tant qu'expression peut être sans accolades uniquement s'il tient sur une seule ligne.
val value = if (string.isEmpty()) 0 else 1 // Okay
val value = if (string.isEmpty()) // WRONG! 0 else 1
val value = if (string.isEmpty()) { // Okay 0 } else { 1 }
Retrait
À chaque nouveau bloc ou élément de type bloc, le retrait est augmenté de quatre espaces. Lorsque le bloc est fermé, le retrait revient au niveau précédent. Le niveau de retrait s'applique au code et aux commentaires du bloc.
Une seule instruction par ligne
Chaque instruction est suivie d'un saut de ligne. Aucun point-virgule n'est utilisé.
Renvoi à la ligne
Le code est limité à 100 caractères par colonne. Sauf indication contraire ci-dessous, les lignes qui dépassent cette limite doivent être encapsulées, comme expliqué plus bas.
Exceptions :
- Lignes ne pouvant pas respecter la limite de colonnes (par exemple, une URL longue dans KDoc)
- Instructions
package
etimport
- Lignes de commande dans un commentaire pouvant être coupées et collées dans une interface système
Où faire un saut de ligne
La première règle à respecter pour les renvois à la ligne est la suivante : il est préférable de faire le saut de ligne à un niveau syntaxique plus élevé. En outre :
- Pour les opérateurs et les fonctions infixe, le saut de ligne se fait après le nom de l'opérateur ou de la fonction infixe.
- Le saut de ligne précède le symbole pour les symboles de type opérateur suivants :
- Le point de séparation (
.
,?.
) - Le double deux-points d'une référence de membre (
::
)
- Le point de séparation (
- Un nom de méthode ou de constructeur reste attaché à la parenthèse ouvrante (
(
) qui le suit - Une virgule (
,
) reste attachée au jeton qui la précède - Une flèche lambda (
->
) reste attachée à la liste d'arguments qui la précède
Fonctions
Lorsqu'une signature de fonction ne tient pas sur une seule ligne, passez à la ligne pour chaque déclaration de paramètre. Les paramètres définis dans ce format doivent utiliser un seul retrait (+4). La parenthèse fermante ()
) et le type renvoyé sont placés sur leur propre ligne sans retrait supplémentaire.
fun <T> Iterable<T>.joinToString( separator: CharSequence = ", ", prefix: CharSequence = "", postfix: CharSequence = "" ): String { // … }
Fonctions d'expression
Lorsqu'une fonction ne contient qu'une seule expression, elle peut être représentée par une fonction d'expression.
override fun toString(): String { return "Hey" }
override fun toString(): String = "Hey"
Propriétés
Lorsqu'un initialiseur de propriété ne tient pas sur une seule ligne, passez à la ligne après le signe égal (=
) et utilisez un retrait.
private val defaultCharset: Charset? = EncodingRegistry.getInstance().getDefaultCharsetForPropertiesFiles(file)
Les propriétés déclarant une fonction get
et/ou set
doivent les placer chacune sur une nouvelle ligne avec un retrait normal (+4). Appliquez les mêmes règles de mise en page que pour les fonctions.
var directory: File? = null set(value) { // … }
val defaultExtension: String get() = "kt"
Espace blanc
Vertical
Ajoutez une seule ligne vide :
- Entre plusieurs membres consécutifs d'une classe : propriétés, constructeurs, fonctions, classes imbriquées, etc.
- Exception : Il est facultatif d'ajouter une ligne vide entre deux propriétés consécutives (sans autre code entre elles). Ces lignes vides sont utilisées si nécessaire pour créer des regroupements logiques de propriétés et associer, le cas échéant, des propriétés à leur propriété de support.
- Exception : Les lignes vides entre les constantes d'énumération sont abordées ci-dessous.
- Entre les instructions si nécessaire pour organiser le code en sous-sections logiques.
- Facultatif (ni conseillé, ni déconseillé) : Avant la première instruction d'une fonction, et avant le premier membre d'une classe ou après le dernier.
- Comme indiqué dans d'autres sections de ce document (telles que la section Structure).
Vous pouvez utiliser plusieurs lignes vides consécutives, mais elles ne sont pas nécessaires ni conseillées.
Horizontal
Outre les cas où le langage ou d'autres règles de style l'exigent, et à l'exception des littéraux, des commentaires et des KDoc, un seul espace ASCII est ajouté uniquement aux emplacements suivants :
- Lors de la séparation d'un mot réservé, tel que
if
,for
oucatch
et d'une parenthèse ouvrante ((
) qui le suit sur la même ligne.// WRONG! for(i in 0..1) { }
// Okay for (i in 0..1) { }
- Lors de la séparation d'un mot réservé, tel que
else
oucatch
et d'une accolade fermante (}
) qui le précède sur la même ligne.// WRONG! }else { }
// Okay } else { }
-
Avant toute accolade ouvrante (
{
).// WRONG! if (list.isEmpty()){ }
// Okay if (list.isEmpty()) { }
-
Des deux côtés d'un opérateur binaire.
// WRONG! val two = 1+1
Cela s'applique également aux symboles de type opérateur suivants: <ph type="x-smartling-placeholder">// Okay val two = 1 + 1
- </ph>
- Flèche dans une expression lambda (
->
).// WRONG! ints.map { value->value.toString() }
// Okay ints.map { value -> value.toString() }
-
Le double deux-points (
::
) d'une référence de membre// WRONG! val toString = Any :: toString
// Okay val toString = Any::toString
-
Le point de séparation (
.
)// WRONG it . toString()
// Okay it.toString()
-
L'opérateur de plage (
..
)// WRONG for (i in 1 .. 4) { print(i) }
// Okay for (i in 1..4) { print(i) }
- Flèche dans une expression lambda (
-
Avant le deux-points (
:
) uniquement s'il est utilisé dans une déclaration de classe pour spécifier une classe de base ou des interfaces, ou s'il est utilisé dans une clausewhere
pour une contrainte générique.// WRONG! class Foo: Runnable
// Okay class Foo : Runnable
// WRONG fun <T: Comparable> max(a: T, b: T)
// Okay fun <T : Comparable> max(a: T, b: T)
// WRONG fun <T> max(a: T, b: T) where T: Comparable<T>
// Okay fun <T> max(a: T, b: T) where T : Comparable<T>
-
Après une virgule (
,
) ou un deux-points (:
)// WRONG! val oneAndTwo = listOf(1,2)
// Okay val oneAndTwo = listOf(1, 2)
// WRONG! class Foo :Runnable
// Okay class Foo : Runnable
-
Des deux côtés de la double barre oblique (
//
) qui commence un commentaire de fin de ligne. Dans ce cas, plusieurs espaces sont autorisés, mais pas obligatoires.// WRONG! var debugging = false//disabled by default
// Okay var debugging = false // disabled by default
Cette règle n'est jamais interprétée comme nécessitant ou interdisant l'ajout d'un espace au début ou à la fin d'une ligne. Elle ne concerne que l'espace intérieur.
Constructions spécifiques
Classes d'énumération
Une énumération sans fonction ni documentation sur ses constantes peut éventuellement être mise en forme sur une seule ligne.
enum class Answer { YES, NO, MAYBE }
Lorsque les constantes d'une énumération sont placées sur des lignes distinctes, aucune ligne vide n'est requise entre elles, sauf si elles définissent un corps.
enum class Answer { YES, NO, MAYBE { override fun toString() = """¯\_(ツ)_/¯""" } }
Étant donné que les énumérations sont des classes, toutes les autres règles de mise en forme qui s'appliquent aux classes s'y appliquent également.
Annotations
Les annotations de type ou de membre sont placées sur des lignes distinctes juste avant la construction annotée.
@Retention(SOURCE) @Target(FUNCTION, PROPERTY_SETTER, FIELD) annotation class Global
Les annotations sans argument peuvent être placées sur une seule ligne.
@JvmField @Volatile var disposable: Disposable? = null
Lorsqu'une seule annotation sans argument est présente, elle peut être placée sur la même ligne que la déclaration.
@Volatile var disposable: Disposable? = null @Test fun selectAll() { // … }
La syntaxe @[...]
ne peut être utilisée qu'avec une cible explicite d'utilisation du site, et uniquement pour combiner au moins deux annotations sans argument sur une seule ligne.
@field:[JvmStatic Volatile] var disposable: Disposable? = null
Types renvoyés/Types de propriétés implicites
Si le corps d'une fonction d'expression ou un initialiseur de propriété est une valeur scalaire ou si le type renvoyé peut être clairement déduit du corps, il peut être omis.
override fun toString(): String = "Hey" // becomes override fun toString() = "Hey"
private val ICON: Icon = IconLoader.getIcon("/icons/kotlin.png") // becomes private val ICON = IconLoader.getIcon("/icons/kotlin.png")
Lorsque vous écrivez une bibliothèque, conservez la déclaration de type explicite si elle fait partie de l'API publique.
Dénominations
Les identifiants n'utilisent que des lettres et des chiffres ASCII, ainsi que des traits de soulignement dans un petit nombre de cas, indiqués ci-dessous. Ainsi, chaque nom d'identifiant valide correspond à l'expression régulière \w+
.
Les préfixes ou suffixes spéciaux, comme ceux des exemples name_
, mName
, s_name
et kName
, ne sont utilisés que dans les propriétés de support (voir Propriétés de support).
Noms des packages
Les noms de packages s'écrivent en minuscules et sont simplement concaténés (sans traits de soulignement).
// Okay package com.example.deepspace // WRONG! package com.example.deepSpace // WRONG! package com.example.deep_space
Noms des types
Les noms de classes sont en PascalCase et représentent en général des noms ou des syntagmes nominaux. Exemples : Character
ou ImmutableList
. Les noms d'interface peuvent également être des noms ou des syntagmes nominaux (par exemple, List
). Parfois, il peut également s'agir d'adjectifs ou de syntagmes adjectivaux (par exemple, Readable
).
Les classes de test portent un nom qui commence par le nom de la classe qu'elles testent et se termine par Test
. Exemples : HashTest
ou HashIntegrationTest
.
Noms des fonctions
Les noms de fonctions sont écrits en camelCase et représentent en général des verbes ou des syntagmes verbaux. Exemples : sendMessage
ou stop
.
Des traits de soulignement peuvent être ajoutés dans les noms de fonctions de test pour séparer leurs composants logiques.
@Test fun pop_emptyStack() { // … }
Les fonctions annotées avec @Composable
qui renvoient Unit
sont en PascalCase et désignés par des noms, comme s'il s'agissait de types.
@Composable fun NameTag(name: String) { // … }
Les noms de fonctions ne doivent pas contenir d'espaces, car elles ne sont pas compatibles avec toutes les plates-formes (en particulier, elles ne sont pas entièrement compatibles avec Android).
// WRONG! fun `test every possible case`() {} // OK fun testEveryPossibleCase() {}
Noms des constantes
Les noms de constantes sont en UPPER_SNAKE_CASE, c'est-à-dire en lettres majuscules avec des mots séparés par des traits de soulignement. Qu'est-ce qu'une constante ?
Une constante est une propriété val
sans fonction get
personnalisée, dont le contenu est immuable et dont les fonctions n'ont aucun effet secondaire détectable. Cela inclut les types immuables et les collections immuables de types immuables, ainsi que les valeurs scalaires et les chaînes si elles sont marquées comme const
. Si l'un des états observables d'une instance peut changer, il ne s'agit pas d'une constante. La seule intention de ne jamais faire muter l'objet ne suffit pas.
const val NUMBER = 5 val NAMES = listOf("Alice", "Bob") val AGES = mapOf("Alice" to 35, "Bob" to 32) val COMMA_JOINER = Joiner.on(',') // Joiner is immutable val EMPTY_ARRAY = arrayOf()
Ces noms représentent en général des noms ou des syntagmes nominaux.
Les valeurs de constante ne peuvent être définies que dans un object
ou en tant que déclaration de niveau supérieur. Les valeurs qui répondent à l'exigence d'une constante, mais qui sont définies à l'intérieur d'une class
doivent utiliser un nom non constant.
Les constantes qui sont des valeurs scalaires doivent utiliser le modificateur const
.
Noms non constants
Les noms non constants sont écrits en camelCase. Cela s'applique aux propriétés d'instance, aux propriétés locales et aux noms de paramètres.
val variable = "var" val nonConstScalar = "non-const" val mutableCollection: MutableSet= HashSet() val mutableElements = listOf(mutableInstance) val mutableValues = mapOf("Alice" to mutableInstance, "Bob" to mutableInstance2) val logger = Logger.getLogger(MyClass::class.java.name) val nonEmptyArray = arrayOf("these", "can", "change")
Ces noms représentent en général des noms ou des syntagmes nominaux.
Propriétés de support
Lorsqu'une propriété de support est nécessaire, son nom doit correspondre exactement à celui de la propriété réelle, à l'exception d'un trait de soulignement en préfixe.
private var _table: Map<String, Int>? = null val table: Map<String, Int> get() { if (_table == null) { _table = HashMap() } return _table ?: throw AssertionError() }
Noms des variables de type
Chaque variable de type est nommée dans l'un des deux styles suivants :
- Une seule lettre majuscule, suivie éventuellement d'un seul chiffre (par exemple,
E
,T
,X
,T2
) - Un nom au format utilisé pour les classes, suivi de la lettre majuscule
T
(par exemple,RequestT
ouFooBarT
)
Camel case
Parfois, iI existe plusieurs façons de convertir une expression anglaise en camelCase, par exemple en présence d'acronymes ou de constructions inhabituelles comme "IPv6" ou "iOS". Pour améliorer la prévisibilité, utilisez le schéma suivant.
En commençant par la forme en prose du nom :
- Convertissez l'expression en ASCII simple et supprimez toutes les apostrophes. Ainsi, "Müller’s algorithm" devient "Muellers algorithm".
- Divisez le résultat en plusieurs mots, séparés par des espaces et par les signes de ponctuation restants (généralement des traits d'union). Recommandé : Si l'un des mots présente déjà une apparence conventionnelle, vous pouvez le diviser en différentes parties (par exemple, "AdWords" devient "ad words"). Notez qu'un terme comme "iOS" n'est pas réellement en Camel Case. Il défie toute convention, cette recommandation ne s'applique donc pas.
- Mettez tout en minuscules (y compris les acronymes), puis effectuez l'une des opérations suivantes :
- Mettez en majuscule le premier caractère de chaque mot pour obtenir le PascalCase.
- Mettez en majuscule le premier caractère de chaque mot, à l'exception du premier mot pour obtenir le PascalCase.
- Regroupez tous les mots en un seul identifiant.
Notez que la casse d'origine est presque entièrement ignorée.
Forme en prose | Correct | Incorrect |
---|---|---|
"XML Http Request" | XmlHttpRequest |
XMLHTTPRequest |
"new customer ID" | newCustomerId |
newCustomerID |
"inner stopwatch" | innerStopwatch |
innerStopWatch |
"supports IPv6 on iOS" | supportsIpv6OnIos |
supportsIPv6OnIOS |
"YouTube importer" | YouTubeImporter |
YoutubeImporter * |
(* Acceptable, mais pas recommandé.)
Documentation
Mise en forme
Voici un exemple de mise en forme de base des blocs KDoc :
/** * Multiple lines of KDoc text are written here, * wrapped normally… */ fun method(arg: String) { // … }
En voici un autre, sur une seule ligne :
/** An especially short bit of KDoc. */
Le format de base est toujours acceptable. La forme à une ligne peut être utilisée lorsque l'intégralité du bloc KDoc (y compris les marqueurs de commentaires) peut tenir sur une seule ligne. Notez que cela ne s'applique que lorsqu'il n'existe aucune balise de bloc comme @return
.
Paragraphes
Une ligne vide, c'est-à-dire ne contenant que l'astérisque de début aligné (*
), est ajoutée entre les paragraphes et, le cas échéant, avant le groupe de balises de bloc.
Balises de bloc
Toutes les balises de bloc standards utilisées apparaissent dans l'ordre @constructor
, @receiver
, @param
, @property
, @return
, @throws
et @see
. Elles n'apparaissent jamais avec une description vide.
Lorsqu'une balise de bloc ne tient pas sur une seule ligne, les lignes de continuation sont mises en retrait de quatre espaces par rapport à la position du @
.
Fragment récapitulatif
Chaque bloc KDoc commence par un bref fragment récapitulatif. Ce fragment est très important : c'est la seule partie du texte qui apparaît dans certains contextes, tels que les index de méthode et de classe.
Il s'agit d'un fragment (un syntagme nominal ou verbal), pas d'une phrase complète.
Un fragment récapitulatif ne commence pas par "A `Foo` is a...
" ou "This method returns...
", et ne doit pas nécessairement former une phrase impérative complète comme "Save the record.
". Cependant, il respecte les majuscules et la ponctuation comme s'il s'agissait d'une phrase complète.
Utilisation
Au minimum, KDoc est présent pour chaque type public
et chaque membre public
ou protected
de ce type, à quelques exceptions près, comme indiqué ci-dessous.
Exception : fonctions explicites
KDoc est facultatif pour les fonctions simples et évidentes comme getFoo
et les propriétés comme foo
, quand il n'y a rien d'autre à dire à part "Returns the foo" (Renvoie le foo).
Il n'est pas approprié de citer cette exception pour justifier l'omission d'informations pertinentes qu'un lecteur type aurait besoin de connaître. Ainsi, pour une fonction nommée getCanonicalName
ou une propriété nommée canonicalName
, n'omettez pas sa documentation (au motif qu'elle ne dirait que /** Returns the canonical name. */
) si le lecteur type ne sait pas ce que signifie le terme "canonical name".
Exception : remplacements
KDoc n'est pas toujours présent dans une méthode qui remplace une méthode de supertype.