Guida di stile Kotlin

Questo documento rappresenta la definizione completa degli standard di programmazione Android di Google per il codice sorgente nel linguaggio di programmazione Kotlin. Un file sorgente Kotlin viene descritto come in stile Google Android solo se ed è conforme alle relative regole.

Come altre guide di stile per la programmazione, i problemi trattati non riguardano solo i problemi estetici della formattazione, ma anche altri tipi di convenzioni o standard di codifica. Tuttavia, questo documento si concentra principalmente sulle regole ferree che seguiamo universalmente ed evita di dare consigli che non sono chiaramente applicabili (da parte di persone fisiche o da uno strumento).

Ultimo aggiornamento: 2023-09-06

File di origine

Tutti i file sorgente devono avere la codifica UTF-8.

Denominazione

Se un file sorgente contiene una sola classe di primo livello, il nome del file deve riflettere il nome sensibile alle maiuscole e l'estensione .kt. Altrimenti, Se un file di origine contiene più dichiarazioni di primo livello, scegli un nome che descrive i contenuti del file, applica PascalCase (camelCase è accettabile se il nome file è plurale) e aggiungi l'estensione .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() = // …

Caratteri speciali

Caratteri per lo spazio vuoto

A parte la sequenza di terminazioni di riga, Carattere di spazio orizzontale ASCII (0x20) è l'unico spazio vuoto che compare in un file di origine. Ciò implica che:

  • Tutti gli altri spazi vuoti presenti nella stringa e nei valori letterali carattere sono sottoposti a escape.
  • I caratteri di tabulazione non vengono utilizzati per il rientro.

Sequenze di escape speciali

Per qualsiasi carattere con una sequenza di escape speciale (\b, \n, \r, \t, \', \", \\ e \$), viene utilizzata questa sequenza al posto del (ad es. \u000a).

Caratteri non ASCII

Per i restanti caratteri non ASCII, il carattere Unicode effettivo (ad es. ) o il carattere di escape Unicode equivalente (ad es. \u221e). La scelta dipende solo da cosa rende il codice più facili da leggere e comprendere. L'utilizzo di caratteri di escape Unicode è sconsigliato per i caratteri stampabili in qualsiasi posizione e sono fortemente sconsigliati al di fuori dei valori letterali di stringa e dei commenti.

Esempio Discussione
val unitAbbrev = "μs" Migliore: perfettamente chiara anche senza commento.
val unitAbbrev = "\u03bcs" // μs Scadente: non c'è motivo di utilizzare un carattere di escape con un carattere stampabile.
val unitAbbrev = "\u03bcs" Scadente: il lettore non ha idea di cosa sia.
return "\ufeff" + content Buona: utilizza caratteri di escape per i caratteri non stampabili e, se necessario, commenta.

Struttura

Un file .kt comprende i seguenti elementi, in ordine:

  • Intestazione per copyright e/o licenza (facoltativa)
  • Annotazioni a livello di file
  • Istruzione pacchetto
  • Importa istruzioni
  • Dichiarazioni di primo livello

Ciascuna di queste sezioni è separata da una riga vuota.

Se l'intestazione di una licenza o di un copyright appartiene al file, deve essere posizionata nella parte superiore immediata di un commento su più righe.

/*
 * Copyright 2017 Google, Inc.
 *
 * ...
 */
 

Non utilizzare uno stile KDoc o un commento di una sola riga.

/**
 * Copyright 2017 Google, Inc.
 *
 * ...
 */
// Copyright 2017 Google, Inc.
//
// ...

Annotazioni a livello di file

Annotazioni con il "file" target sito d'uso Vengono posizionati tra qualsiasi commento dell'intestazione e la dichiarazione relativa al pacchetto.

Istruzione pacchetto

L'istruzione del pacchetto non è soggetta a limiti di colonne e non è mai aggregata a una riga.

Importa istruzioni

Le istruzioni di importazione per classi, funzioni e proprietà sono raggruppate in un unico elenco e ordinate in ASCII.

Le importazioni con caratteri jolly (di qualsiasi tipo) non sono consentite.

Analogamente all'istruzione pacchetto, le istruzioni di importazione non sono soggette a un limite di colonne e non viene mai aggregato.

Dichiarazioni di primo livello

Un file .kt può dichiarare uno o più tipi, funzioni, proprietà o tipi alias di primo livello.

I contenuti di un file devono essere incentrati su un singolo tema. Esempi un singolo tipo pubblico o un insieme di funzioni di estensione che eseguono la stessa operazione su più tipi di ricevitori. Le dichiarazioni non correlate devono essere separati in file separati e dichiarazioni pubbliche all'interno di un unico file devono essere ridotti al minimo.

Non viene applicata alcuna restrizione esplicita al numero o all'ordine dei contenuti di un file.

I file di origine vengono generalmente letti dall'alto verso il basso, il che significa che l'ordine, in in generale, dovrebbe riflettere il fatto che le dichiarazioni più in alto informeranno comprendendo anche quelli più in basso. È possibile ordinare diversi file i contenuti in modo diverso. Analogamente, un file può contenere 100 proprietà, altre 10 funzioni e ancora una sola classe.

È importante che ogni file utilizzi un certo ordine logico, ovvero potrebbe spiegare se richiesto. Ad esempio, le nuove funzioni non sono abitualmente aggiunti alla fine del file, in quanto ciò produrrebbe una "cronologica" per data di aggiunta", che non è un ordinamento logico.

Ordinazione dei membri del corso

L'ordine dei membri all'interno di un corso segue le stesse regole dei membri di primo livello dichiarazioni.

Formattazione

Tutori

Le parentesi graffe non sono necessarie per i rami when e le espressioni if che non hanno più di un ramo else e che rientrano in una singola riga.

if (string.isEmpty()) return

val result =
    if (string.isEmpty()) DEFAULT_VALUE else string

when (value) {
    0 -> return
    // …
}

Le parentesi graffe sono altrimenti obbligatorie per qualsiasi filiale if, for, when, do, e while, anche quando il corpo è vuoto o contiene solo una singola istruzione.

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)
}

Blocchi non vuoti

Le parentesi graffe seguono lo stile Kernighan e Ritchie ("parentesi egizie") per blocchi non vuoti e costrutti simili a blocchi:

  • Nessuna interruzione di riga prima della parentesi graffa di apertura.
  • Interruzione di riga dopo la parentesi graffa di apertura.
  • Interruzione di riga prima della parentesi graffa di chiusura.
  • Interruzione di riga dopo la parentesi graffa di chiusura, solo se termina una o termina il corpo di una funzione, un costruttore o una classe named. Ad esempio, non c'è interruzione di riga dopo la parentesi graffa se è seguita da else o una virgola.
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()
        }
    }
}

Alcune eccezioni per classi enum sono riportati di seguito.

Blocchi vuoti

Un blocco o un costrutto vuoto deve essere in stile K&R.

try {
    doSomething()
} catch (e: Exception) {} // WRONG!
try {
    doSomething()
} catch (e: Exception) {
} // Okay

Espressioni

Un condizionale if/else utilizzato come espressione può ometti le parentesi graffe solo se l'intera espressione rientra in una sola riga.

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
}

Rientro

Ogni volta che viene aperto un nuovo blocco o costrutto simile a un blocco, il rientro aumenta di quattro spazi. Al termine del blocco, il rientro torna al livello precedente. Il livello di rientro si applica sia al codice sia ai commenti in tutto il blocco.

Un'istruzione per riga

Ogni istruzione è seguita da un'interruzione di riga. I punti e virgola non vengono utilizzati.

A capo automatico

Il codice ha un limite di 100 caratteri per le colonne. Fatto salvo quanto indicato di seguito, le righe che superano questo limite devono essere aggregate a capo, come spiegato di seguito.

Eccezioni:

  • Righe in cui non è possibile rispettare il limite delle colonne (ad es. un URL lungo in un file KDoc)
  • Estratti conto package e import
  • Righe di comando in un commento che possono essere tagliate e incollate in una shell

Dove interrompere

La principale direttiva del wrapping di righe è la preferenza per l'interruzione a un livello sintattico più elevato. Inoltre:

  • Quando una linea è spezzata in corrispondenza del nome di un operatore o di una funzione infissa, l'interruzione compare dopo il nome dell'operatore o della funzione infissa.
  • Quando una linea è spezzata in corrispondenza dei seguenti simboli "simili a un operatore", la interruzione precede il simbolo:
    • Il separatore del punto (., ?.).
    • I due punti del riferimento di un membro (::).
  • Un metodo o un nome di costruttore rimane collegato alla parentesi aperta (() che la seguite.
  • Una virgola (,) rimane collegata al token che la precede.
  • Una freccia lambda (->) rimane collegata all'elenco di argomenti che la precede.
di Gemini Advanced.

Funzioni

Quando la firma di una funzione non rientra in una sola riga, spezza ogni dichiarazione di parametro su una riga separata. I parametri definiti in questo formato devono utilizzare un rientro singolo (+4). Le parentesi di chiusura ()) e il tipo restituito vengono posizionati su una propria riga senza rientro aggiuntivo.

fun <T> Iterable<T>.joinToString(
    separator: CharSequence = ", ",
    prefix: CharSequence = "",
    postfix: CharSequence = ""
): String {
    // …
}
Funzioni di espressione

Quando una funzione contiene solo una singola espressione, può essere rappresentata come funzione di espressione.

override fun toString(): String {
    return "Hey"
}
override fun toString(): String = "Hey"

Proprietà

Quando un inizializzatore di proprietà non rientra in una singola riga, inserisci un'interruzione dopo il segno di uguale (=) e utilizza un rientro.

private val defaultCharset: Charset? =
    EncodingRegistry.getInstance().getDefaultCharsetForPropertiesFiles(file)

Le proprietà che dichiarano una funzione get e/o set devono posizionarle ciascuna alla propria riga con un rientro normale (+4). Formattale utilizzando le stesse regole come funzioni.

var directory: File? = null
    set(value) {
        // …
    }
Le proprietà di sola lettura possono utilizzare una sintassi più breve che si adatta a una singola riga.
val defaultExtension: String get() = "kt"

Spazio vuoto

Verticale

Viene visualizzata una singola riga vuota:

  • Tra membri consecutivi di una classe: proprietà, costruttori funzioni, classi nidificate e così via.
      .
    • Eccezione: una riga vuota tra due proprietà consecutive (senza altri codici tra loro) è facoltativo. Queste righe vuote vengono utilizzate all'occorrenza per creare raggruppamenti logici di proprietà e proprietà associate con la relativa proprietà di supporto, se presente.
    • Eccezione: vengono coperte le righe vuote tra le costanti enum. di seguito.
  • Tra le istruzioni, se necessario per organizzare il codice in sottosezioni logiche.
  • Facoltativamente prima della prima istruzione in una funzione, prima del primo membro di una classe o dopo l'ultimo membro di una (né incoraggiati né scoraggiati).
  • Come richiesto da altre sezioni del presente documento (come il Struttura).

Più righe vuote consecutive sono consentite, ma non consigliate o mai richiesto.

Orizzontale

Oltre a dove richiesto dalla lingua o da altre regole di stile, e, a parte i valori letterali, i commenti e i documenti KDoc, un'unica e viene visualizzato solo nelle seguenti posizioni:

  • Separazione di qualsiasi parola riservata, ad esempio if, for, oppure catch da una parentesi aperta (() che la segue su quella riga.
    // WRONG!
    for(i in 0..1) {
    }
    
    // Okay
    for (i in 0..1) {
    }
    
  • Separazione di qualsiasi parola riservata, ad esempio else o catch, da un parentesi graffa chiusa (}) che la precede su tale riga.
    // WRONG!
    }else {
    }
    
    // Okay
    } else {
    }
    
  • Prima di qualsiasi parentesi graffa aperta ({).
    // WRONG!
    if (list.isEmpty()){
    }
    
    // Okay
    if (list.isEmpty()) {
    }
    
  • Su entrambi i lati di qualsiasi operatore binario.
    // WRONG!
    val two = 1+1
    
    // Okay
    val two = 1 + 1
    
    Questo vale anche per i seguenti simboli "simili a un operatore":
      .
    • la freccia in un'espressione lambda (->).
      // WRONG!
      ints.map { value->value.toString() }
      
      // Okay
      ints.map { value -> value.toString() }
      
    di Gemini Advanced. ma non:
    • i due due punti (::) di un riferimento di membro.
      // WRONG!
      val toString = Any :: toString
      
      // Okay
      val toString = Any::toString
      
    • il separatore del punto (.).
      // WRONG
      it . toString()
      
      // Okay
      it.toString()
      
    • l'operatore di intervallo (..).
      // WRONG
      for (i in 1 .. 4) {
        print(i)
      }
      
      // Okay
      for (i in 1..4) {
        print(i)
      }
      
  • Prima dei due punti (:) solo se utilizzati in una dichiarazione di classe per specificare una o più interfacce di base oppure quando utilizzate in una clausola where della . vincoli generici.
    // 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>
    
  • Dopo una virgola (,) o due punti (:).
    // WRONG!
    val oneAndTwo = listOf(1,2)
    
    // Okay
    val oneAndTwo = listOf(1, 2)
    
    // WRONG!
    class Foo :Runnable
    
    // Okay
    class Foo : Runnable
    
  • Su entrambi i lati della doppia barra (//) che inizia un commento alla fine della riga. In questo caso, sono consentiti più spazi, ma non sono obbligatori.
    // WRONG!
    var debugging = false//disabled by default
    
    // Okay
    var debugging = false // disabled by default
    

Questa regola non viene mai interpretata come richiesta o divieto di offerte spazio aggiuntivo all'inizio o alla fine di una riga; solo gli indirizzi spazio interno.

Costrutti specifici

Classi enum

Un'enumerazione senza funzioni e senza documentazione sulle sue costanti può facoltativamente essere formattata come una singola riga.

enum class Answer { YES, NO, MAYBE }

Quando le costanti di un'enumerazione vengono posizionate su righe separate, non è necessaria una riga vuota tra loro, tranne nel caso in cui definiscano un corpo.

enum class Answer {
    YES,
    NO,

    MAYBE {
        override fun toString() = """¯\_(ツ)_/¯"""
    }
}

Poiché le classi enum sono classi, vengono applicate tutte le altre regole per le classi di formattazione.

Annotazioni

Le annotazioni di membri o tipi vengono posizionate su righe separate immediatamente prima del costrutto annotato.

@Retention(SOURCE)
@Target(FUNCTION, PROPERTY_SETTER, FIELD)
annotation class Global

Le annotazioni senza argomenti possono essere inserite su una singola riga.

@JvmField @Volatile
var disposable: Disposable? = null

Quando è presente una sola annotazione senza argomenti, potrebbe essere posizionato nella stessa riga della dichiarazione.

@Volatile var disposable: Disposable? = null

@Test fun selectAll() {
    // …
}

La sintassi @[...] può essere utilizzata solo con un target di sito per l'utilizzo esplicito e solo per che combina due o più annotazioni senza argomenti su un'unica riga.

@field:[JvmStatic Volatile]
var disposable: Disposable? = null

Tipi di restituzione/proprietà impliciti

Se il corpo di una funzione di espressione o un inizializzatore di proprietà è uno scalare o il tipo restituito possa essere dedotto chiaramente dal corpo, può essere omesso.

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")

Quando scrivi una libreria, mantieni la dichiarazione di tipo esplicita quando fa parte dell'API pubblica.

Denominazione

Gli identificatori utilizzano solo lettere e cifre ASCII e, in un numero limitato di casi indicati di seguito, trattini bassi. Pertanto, ogni nome di identificatore valido corrisponde all'espressione regolare \w+.

Prefissi o suffissi speciali, come quelli mostrati negli esempi name_, mName, s_name e kName non vengono utilizzati, tranne che nel caso di: delle proprietà di supporto (vedi Proprietà di supporto).

Nomi pacchetto

I nomi dei pacchetti sono tutti minuscoli e contengono parole consecutive concatenati (senza trattini bassi).

// Okay
package com.example.deepspace
// WRONG!
package com.example.deepSpace
// WRONG!
package com.example.deep_space

Nomi dei tipi

I nomi delle classi sono scritti in PascalCase e di solito sono sostantivi frasi chiave. Ad esempio, Character o ImmutableList. I nomi delle interfacce possono essere anche sostantivi o frasi sostantivi (ad esempio, List), ma a volte possono essere aggettivi o espressioni aggettive (ad esempio Readable).

Il nome delle classi di test inizia con il nome della classe che stanno testando, e termina con Test. Ad esempio, HashTest o HashIntegrationTest.

Nomi delle funzioni

I nomi delle funzioni sono scritti in camelCase e sono generalmente verbi o frasi di verbi. Ad esempio, sendMessage o stop.

Nei nomi delle funzioni di test possono essere visualizzati trattini bassi per separare i componenti logici del nome stesso.

@Test fun pop_emptyStack() {
    // …
}

Le funzioni annotate con @Composable che restituiscono Unit sono maiuscole e minuscole e denominate come sostantivi, come se fossero tipi.

@Composable
fun NameTag(name: String) {
    // …
}

I nomi delle funzioni non devono contenere spazi perché non è supportato completamente supportata su Android.

// WRONG!
fun `test every possible case`() {}
// OK
fun testEveryPossibleCase() {}

Nomi costanti

I nomi delle costanti utilizzano UPPER_SNAKE_CASE: tutte lettere maiuscole, con parole separate da trattini bassi. Ma cosa è una costante, esattamente?

Le costanti sono proprietà val senza funzione get personalizzata, i cui contenuti sono sono profondamente immutabili e le cui funzioni non presentano effetti collaterali rilevabili. Questo include tipi immutabili e raccolte immutabili di tipi immutabili così come scalari e stringa, se contrassegnati come const. Se una delle istanze osservabile può cambiare, non è una costante. Semplicemente con l'intenzione di non è sufficiente modificare mai l'oggetto.

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()

Questi nomi sono in genere sostantivi o frasi sostantivi.

I valori costanti possono essere definiti solo all'interno di un object o una dichiarazione di primo livello. Valori che altrimenti soddisfano il requisito costante, ma definita all'interno di un valore class, deve utilizzare un nome non costante.

Le costanti che sono valori scalari devono usare const modificatore.

Nomi non costanti

I nomi non costanti sono scritti in camelCase. Si applicano alle proprietà dell'istanza, alle proprietà locali e ai nomi dei parametri.

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")

Questi nomi sono in genere sostantivi o frasi sostantivi.

Proprietà di supporto

Quando proprietà di supporto , il suo nome deve corrispondere esattamente a quello della proprietà reale tranne che è preceduto da un trattino basso.

private var _table: Map? = null

val table: Map
    get() {
        if (_table == null) {
            _table = HashMap()
        }
        return _table ?: throw AssertionError()
    }

Digita i nomi delle variabili

A ogni variabile di tipo viene assegnato un nome in uno dei due seguenti stili:

  • Una sola lettera maiuscola, facoltativamente seguita da una numero singolo (ad esempio E, T, X, T2)
  • Un nome nel formato utilizzato per le classi, seguito dalla lettera maiuscola lettera T (ad esempio RequestT, FooBarT)

Custodia in cammello

A volte c'è più di un modo ragionevole per convertire una frase inglese in "cammello", ad esempio quando sono presenti acronimi o costrutti insoliti come "IPv6" o "iOS". Per migliorare la prevedibilità, utilizza lo schema seguente.

Comincia con la prosa del nome:

  1. Converti la frase in ASCII normale e rimuovi eventuali apostrofi. Ad esempio, "algoritmo di Müller" potrebbe diventare "algoritmo di Müller".
  2. Dividi questo risultato in parole, dividendo in base agli spazi e all'eventuale punteggiatura rimanente (di solito i trattini). Consigliato: se una parola ha già un aspetto convenzionale a cammello nell'uso comune, suddividilo nelle sue parti costitutive (ad es. "Google Ads" diventa "parole dell'annuncio"). Tieni presente che una parola come "iOS" non è di per sé un caso d'uso. è in contrasto con qualsiasi convenzione, pertanto questo consiglio non si applica.
  3. Ora tutte le lettere devono essere minuscole (inclusi gli acronimi), quindi procedi in uno dei seguenti modi:
    • Utilizza l'iniziale maiuscola per il primo carattere di ogni parola per ottenere il formato pascal.
    • Deve usare l'iniziale maiuscola per il primo carattere di ogni parola, tranne il primo che restituisce. custodia a cammello.
  4. Infine, unisci tutte le parole in un unico identificatore.

Tieni presente che le lettere maiuscole e minuscole delle parole originali vengono quasi ignorate.

Modulo in prosa Corretto Risposta sbagliata
"Richiesta HTTP XML" XmlHttpRequest XMLHTTPRequest
"nuovo ID cliente" newCustomerId newCustomerID
"cronometro interno" innerStopwatch innerStopWatch
"supporta IPv6 su iOS" supportsIpv6OnIos supportsIPv6OnIOS
"Importatore di YouTube" YouTubeImporter YoutubeImporter*

(* Accettabile, ma sconsigliata.)

Documentazione

Formattazione

In questo esempio viene mostrata la formattazione di base dei blocchi KDoc:

/**
 * Multiple lines of KDoc text are written here,
 * wrapped normally…
 */
fun method(arg: String) {
    // …
}

...o in questo esempio di una sola riga:

/** An especially short bit of KDoc. */

Il formato di base è sempre accettabile. Il modulo a una sola riga può essere sostituiti quando l'intero blocco di documenti KDoc (inclusi gli indicatori di commento) possono essere adattati su una sola riga. Tieni presente che ciò si applica solo quando non sono che bloccano tag come @return.

Paragrafi

Una riga vuota, ovvero una riga contenente solo l'asterisco iniziale allineato (*): compare tra i paragrafi e prima del gruppo di tag di blocco, se presente.

Blocca tag

Tutti i "tag di blocco" standard utilizzati appaiono nell'ordine @constructor, @receiver, @param, @property, @return, @throws, @see, che non vengono mai visualizzati con una descrizione vuota. Quando un tag di blocco non rientra su una sola riga, le righe di continuazione sono rientrate di 4 spazi rispetto alla posizione di @.

Frammento di riepilogo

Ogni blocco KDoc inizia con un breve frammento di riepilogo. Questo frammento è molto importante: è l'unica parte del testo che appare in determinati contesti, come gli indici di classi e metodi.

È un frammento, una frase sostantiva o verbale, non una frase completa. Non inizia con "A `Foo` is a...", o "This method returns...", né deve formare una frase imperativa completa come "Save the record.". Tuttavia, il frammento è in maiuscolo e con la punteggiatura completa.

Utilizzo

Come minimo, un documento KDoc è presente per ogni tipo public, e ogni membro public o protected di questo tipo, con alcune eccezioni indicate di seguito.

Eccezione: funzioni autoesplicative

Il documento KDoc è facoltativo per funzioni "semplici e ovvie" come getFoo e proprietà come foo, nei casi in cui non c'è altro da dire se non "restituisce il foo".

Non è appropriato citare questa eccezione per giustificare l'omissione di elementi pertinenti informazioni che un lettore tipico potrebbe avere bisogno di conoscere. Ad esempio, per una funzione denominata getCanonicalName o una proprietà denominata canonicalName, di non omettere la relativa documentazione (con il ragionamento che direbbe /** Returns the canonical name. */) se un lettore tipico potrebbe non avere idea del termine "nome canonico" significa!

Eccezione: override

KDoc non è sempre presente su un metodo che sostituisce un metodo supertipo.