Ten dokument stanowi pełną definicję standardów Google dotyczących kodowania Androida w przypadku kodu źródłowego w języku programowania Kotlin. Plik źródłowy Kotlin jest opisany jako w stylu Google Android Style tylko pod warunkiem, że jest zgodny z niniejszymi zasadami.
Podobnie jak w przypadku innych przewodników dotyczących stylu programowania, poruszane tu problemy obejmują nie tylko problemy estetyczne z formatowaniem, ale także inne rodzaje konwencji i standardów kodowania. W tym dokumencie skupiamy się jednak głównie na sztywnych i szybkich zasadach, których przestrzegamy powszechnie, i nie udziela porad, których nie można wyegzekwować przez człowieka lub przy użyciu narzędzi.
Ostatnia aktualizacja: 6 września 2023 r.
Pliki źródłowe
Wszystkie pliki źródłowe muszą mieć kodowanie UTF-8.
Nazewnictwo
Jeśli plik źródłowy zawiera tylko jedną klasę najwyższego poziomu, nazwa pliku
powinna zawierać nazwę z uwzględnieniem wielkości liter oraz rozszerzenie .kt
. W przeciwnym razie
jeśli plik źródłowy zawiera wiele deklaracji najwyższego poziomu, wybierz nazwę
który opisuje zawartość pliku, zastosuj PascalCase (camelCase to
jest dopuszczalne, jeśli nazwa pliku zawiera liczbę mnogą) i dołączaj rozszerzenie .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() = // …
Znaki specjalne
Znaki odstępów
Oprócz sekwencji zakończenia wiersza funkcja Odstęp ASCII w poziomie (0 x 20) to jedyny znak odstępu występujący w dowolnym miejscu pliku źródłowego. Oznacza to, że:
- Wszystkie pozostałe znaki odstępu w ciągach znaków i literałach znaków podlegają zmianie znaczenia.
- Znaki tabulacji nie służą do wcięć.
Specjalne sekwencje zmiany znaczenia
Dotyczy dowolnych znaków ze specjalną sekwencją zmiany znaczenia.
(\b
, \n
, \r
, \t
, \'
, \"
, \\
i \$
),
używana jest ta sekwencja zamiast odpowiadającego jej Unicode.
(np. \u000a
).
Znaki spoza zestawu ASCII
W przypadku pozostałych znaków spoza zestawu ASCII jest to rzeczywisty znak Unicode.
(np. ∞
) lub równoważny kod zmiany znaczenia Unicode (np. \u221e
).
Wybór zależy tylko od tego, który kod
łatwiej je przeczytać i zrozumieć.
Nie zalecamy zmiany znaczenia znaków w kodzie Unicode w przypadku znaków, które można wydrukować w dowolnym miejscu.
są zdecydowanie odradzane poza literałami łańcuchowymi i komentarzami.
Przykład | Dyskusja |
---|---|
val unitAbbrev = "μs" |
Najlepsza: jasne, nawet bez komentarza. |
val unitAbbrev = "\u03bcs" // μs |
Kiepsko: nie ma powodu, by używać znaków ucieczki z postacią do wydrukowania. |
val unitAbbrev = "\u03bcs" |
Kiepsko: czytelnik nie ma pojęcia, co to jest. |
return "\ufeff" + content |
Dobra: w przypadku znaków niedrukowalnych użyj zmiany znaczenia, a w razie potrzeby dodaj komentarz. |
Struktura
Plik .kt
zawiera w kolejności:
- Nagłówek dotyczący praw autorskich lub licencji (opcjonalnie)
- Adnotacje na poziomie pliku
- Instrukcje dotyczące pakietu
- Importuj instrukcje
- Deklaracje najwyższego poziomu
Każdą z tych sekcji rozdziela dokładnie 1 pusty wiersz.
Prawa autorskie / licencja
Jeśli w pliku znajduje się nagłówek dotyczący praw autorskich lub licencji, umieść go na samej górze w wielowierszowym komentarzu.
/* * Copyright 2017 Google, Inc. * * ... */
Nie używaj stylu KDoc. lub jednowierszowy komentarz.
/** * Copyright 2017 Google, Inc. * * ... */
// Copyright 2017 Google, Inc. // // ...
Adnotacje na poziomie pliku
Adnotacje z plikiem „file” własna witryna docelowa są umieszczane między komentarzem nagłówka a deklaracją pakietu.
Instrukcje dotyczące pakietu
Instrukcje dotyczące pakietu nie podlegają żadnym limitom kolumn i nigdy nie są zawijane do wierszy.
Importuj instrukcje
Instrukcje importu dla klas, funkcji i właściwości są zgrupowane na jednej liście i sortowane według znaków ASCII.
Importy z użyciem symboli wieloznacznych (jakiegokolwiek typu) są niedozwolone.
Podobnie jak w przypadku deklaracji dotyczącej pakietu, instrukcje importu nie podlegają i nigdy nie są zawijane wierszy.
Deklaracje najwyższego poziomu
Plik .kt
może zadeklarować co najmniej 1 typ, funkcję, właściwości lub typ
na najwyższym poziomie.
Zawartość pliku powinna dotyczyć pojedynczego motywu. Przykłady byłby jednym typem publicznym lub zbiorem funkcji rozszerzeń wykonujących tę samą operację na różnych typach odbiorników. Niepowiązane deklaracje powinny być oddzielone na własne pliki i publiczne deklaracje w jednym pliku powinno zostać zminimalizowane.
Nie nakładamy żadnych wyraźnych ograniczeń na liczbę ani kolejność treści plik.
Pliki źródłowe są zwykle odczytywane od góry do dołu, co oznacza, że w kolejności ogólne, powinno odzwierciedlać, że deklaracje wyżej będą informować co dzieje się dalej. Różne pliki mogą się zdecydować na zamówienie ich treść w różny sposób. Podobnie 1 plik może zawierać 100 właściwości, kolejne 10 funkcji i kolejną jedną klasę.
Ważne jest, aby każdy plik był w określonej kolejności logicznej, opiekun klienta może wyjaśnić, jeśli zostanie o to poproszony. Na przykład nowe funkcje to nie tylko są regularnie dodawane na końcu pliku, co zapewnia „chronologiczną” według daty dodania”, która nie jest logiczna.
Sortowanie uczestników zajęć
Kolejność uczestników zajęć jest zgodna z tymi samymi regułami co w przypadku klasy najwyższego poziomu deklaracje.
Formatowanie
Aparaty ortodontyczne
Nawiasy nie są wymagane w przypadku gałęzi when
i wyrażeń if
które mają nie więcej niż jedną gałęzie else
i mieszczą się w jednej linii.
if (string.isEmpty()) return val result = if (string.isEmpty()) DEFAULT_VALUE else string when (value) { 0 -> return // … }
Nawiasy klamrowe są wymagane w przypadku każdej gałęzi if
, for
, when
, do
,
i while
instrukcji i wyrażeń, nawet jeśli treść jest pusta lub zawiera tylko
pojedyncza instrukcja.
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) }
Niepuste bloki
Aparaty są zgodne ze stylem Kernighan i Ritchie („nawiasy egipskie”), w których niepuste bloki i konstrukcje blokowe:
- Brak podziału wiersza przed nawiasem otwierającym.
- Podział wiersza po otwierającym nawiasie klamrowym.
- Podział wiersza przed zamykającym nawiasem klamrowym.
- Podział wiersza po zamykającym nawiasie klamrowym tylko wtedy, gdy dany nawias zamyka nawias klamrowy.
lub kończy treść funkcji, konstruktora lub klasy nazwanej.
Na przykład: nie ma podziału wiersza po nawiasie klamrowym, po którym następuje znak
else
lub przecinek.
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() } } }
Kilka wyjątków dla: klasy wyliczeniowe podane niżej.
Puste bloki
Pusty blok lub konstrukcja blokowa musi być w stylu K&R.
try { doSomething() } catch (e: Exception) {} // WRONG!
try { doSomething() } catch (e: Exception) { } // Okay
Wyrażenia
Warunek if/else
używany jako wyrażenie może
pomijaj nawiasy klamrowe tylko wtedy, gdy całe wyrażenie mieści się w jednym wierszu.
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 }
Wcięcie
Przy każdym otwarciu nowej bryły lub konstrukcji bryłowej wcięcie zwiększa się o cztery spacje. Po zakończeniu bryły wcięcie wróci do poprzedniego poziomu wcięcia. Poziom wcięcia odnosi się zarówno do kodu, jak i komentarzy w całym bloku.
Jedna instrukcja w wierszu
Po każdej instrukcji znajduje się znak podziału wiersza. Średniki nie są używane.
Zawijanie wierszy
Kod może zawierać maksymalnie 100 znaków w kolumnach. Z wyjątkiem przypadków opisanych poniżej każdy wiersz, który przekraczałby ten limit, musi być zawijany w sposób opisany poniżej.
Wyjątki:
- Wiersze, przy których przestrzeganie limitu kolumn jest niemożliwe (na przykład długi adres URL w pliku KDoc)
- Wyciągi
package
iimport
- Wiersze poleceń w komentarzu, które można wyciąć i wkleić do powłoki
Gdzie zrobić przerwę
Najważniejsza dyrektywa w zakresie zawijania wierszy to: preferować podział na wyższym poziomie składni. Poza tym:
- Jeśli wiersz jest zerwany w operatorze lub nazwie funkcji przyrostowej, po nazwie operatora lub funkcji przyrostowej.
- Jeśli linia jest łamana obok następujących symboli podobnych do operatorów, podział
znajduje się przed symbolem:
- Separator kropek (
.
,?.
). - Dwa dwukropki odniesienia do członka (
::
).
- Separator kropek (
- Nazwa metody lub konstruktora pozostaje dołączona do otwartego nawiasu (
(
), który zgodnie z nim. - Przecinek (
,
) pozostaje dołączony do poprzedzającego go tokena. - Strzałka lambda (
->
) pozostaje dołączona do poprzedzającej ją listy argumentów.
Funkcje
Jeśli podpis funkcji nie mieści się w jednym wierszu, rozdziel każdą deklarację parametrów do osobnego wiersza. Parametry zdefiniowane w tym formacie powinny mieć pojedyncze wcięcie (+4). Nawias zamykający ()
) i typ zwracany są umieszczone w osobnym wierszu bez dodatkowego wcięcia.
fun <T> Iterable<T>.joinToString( separator: CharSequence = ", ", prefix: CharSequence = "", postfix: CharSequence = "" ): String { // … }
Funkcje wyrażeń
Jeśli funkcja zawiera tylko jedno wyrażenie, może zostać przedstawiona jako funkcji wyrażenia.
override fun toString(): String { return "Hey" }
override fun toString(): String = "Hey"
Właściwości
Gdy inicjator właściwości nie mieści się w jednym wierszu, poprzedź znak równości (=
) i użyj wcięcia.
private val defaultCharset: Charset? = EncodingRegistry.getInstance().getDefaultCharsetForPropertiesFiles(file)
Właściwości deklarujące funkcję get
lub set
powinny umieszczać każdą z nich na
własny wiersz ze zwykłym wcięciem (+4). Sformatuj je przy użyciu tych samych reguł
.
var directory: File? = null set(value) { // … }
val defaultExtension: String get() = "kt"
Odstęp
Branża
Pojawi się jeden pusty wiersz:
- Między kolejnymi elementami klasy: właściwości, konstruktory,
funkcje, klasy zagnieżdżone itp.
- Wyjątek: pusty wiersz między dwiema wartościami. następujące po sobie właściwości (bez innego kodu między nimi) jest opcjonalna. Takie puste wiersze są używane w razie potrzeby do utworzenia logiczne grupy usług i ich powiązanie z właściwą bazą danych, jeśli istnieje.
- Wyjątek: ukryte są puste linie między stałymi wyliczeniami. poniżej.
- Pomiędzy instrukcjami w razie potrzeby w celu uporządkowania kodu na logiczne podsekcje.
- Opcjonalnie przed pierwszą instrukcją w funkcji przed pierwszym członkiem zajęć lub po ostatnim członkowi zajęć zajęcia (nie zachęca się ani nie zniechęca).
- Zgodnie z wymogami innych sekcji tego dokumentu (np. Struktura).
Dozwolone jest wiele następujących po sobie pustych wierszy, ale nie jest to zalecane. kiedykolwiek wymagane.
Pozioma
Oprócz tego, że wymagają tego ustawienia języka lub innych reguł stylu, oraz literał, komentarze i dokument KDoc, pojedynczy kod ASCII spacja pojawia się również tylko w następujących miejscach:
- Oddzielając dowolne zastrzeżone słowo, np.
if
,for
lubcatch
z nawiasu otwierającego ((
), który następuje po nim w tym wierszu.// WRONG! for(i in 0..1) { }
// Okay for (i in 0..1) { }
- Oddzielenie dowolnego zastrzeżonego słowa, np.
else
lubcatch
, z zamykający nawias klamrowy (}
), który poprzedza go w tej linii.// WRONG! }else { }
// Okay } else { }
-
Przed dowolnym otwartym nawiasem klamrowym (
{
).// WRONG! if (list.isEmpty()){ }
// Okay if (list.isEmpty()) { }
-
Po obu stronach dowolnego operatora binarnego.
// WRONG! val two = 1+1
Dotyczy to również tych symboli podobnych do operatorów:// Okay val two = 1 + 1
- .
- strzałka w wyrażeniu lambda (
->
).// WRONG! ints.map { value->value.toString() }
// Okay ints.map { value -> value.toString() }
-
dwukropki (
::
) odwołania do elementu członkowskiego.// WRONG! val toString = Any :: toString
// Okay val toString = Any::toString
-
separatorem kropek (
.
).// WRONG it . toString()
// Okay it.toString()
-
operator zakresu (
..
).// WRONG for (i in 1 .. 4) { print(i) }
// Okay for (i in 1..4) { print(i) }
- strzałka w wyrażeniu lambda (
-
Przed dwukropkiem (
:
) tylko wtedy, gdy jest używany w deklaracji klasy do określenia klasę bazową lub interfejsy bądź jej użycie w klauzuliwhere
. w przypadku ogólnych ograniczeń.// 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>
-
Po przecinku (
,
) lub dwukropku (:
).// WRONG! val oneAndTwo = listOf(1,2)
// Okay val oneAndTwo = listOf(1, 2)
// WRONG! class Foo :Runnable
// Okay class Foo : Runnable
-
Po obu stronach ukośnika podwójnego (
//
), który zaczyna się na końcu wiersza. W tym przypadku można wpisać wiele spacji, ale nie jest to wymagane.// WRONG! var debugging = false//disabled by default
// Okay var debugging = false // disabled by default
Ta reguła nigdy nie jest interpretowana jako wymagająca lub zabroniona dodatkowe miejsce na początku lub na końcu wiersza; dotyczy tylko do wewnątrz.
Konkretne konstrukcje
Klasy typu wyliczeniowego
Wyliczenie bez funkcji i bez dokumentacji stałych można opcjonalnie sformatować jako pojedynczy wiersz.
enum class Answer { YES, NO, MAYBE }
Gdy stałe w wygenerowaniu znajdują się w osobnych wierszach, nie muszą one oddzielać pustych wierszy. Wyjątkiem są sytuacje, gdy definiują treść.
enum class Answer { YES, NO, MAYBE { override fun toString() = """¯\_(ツ)_/¯""" } }
Klasy typu wyliczeniowego są klasami, więc obowiązują wszystkie inne reguły formatowania.
Adnotacje
Adnotacje członka lub typu są umieszczane w osobnych wierszach bezpośrednio przed konstrukcją z adnotacjami.
@Retention(SOURCE) @Target(FUNCTION, PROPERTY_SETTER, FIELD) annotation class Global
Adnotacje bez argumentów można umieszczać w jednym wierszu.
@JvmField @Volatile var disposable: Disposable? = null
Gdy istnieje tylko jedna adnotacja bez argumentów, można umieścić w tym samym wierszu co deklaracja.
@Volatile var disposable: Disposable? = null @Test fun selectAll() { // … }
Składni @[...]
można używać tylko z jawnym miejscem docelowym w witrynie i tylko w przypadku:
przez połączenie co najmniej 2 adnotacji bez argumentów w jednym wierszu.
@field:[JvmStatic Volatile] var disposable: Disposable? = null
Pośredni zwrot/typy usług
Jeśli treść funkcji wyrażenia lub inicjator właściwości jest wartością skalarną lub typ zwracanego towaru można łatwo wywnioskować z treści, a następnie można pominąć.
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")
Pisząc bibliotekę, zachowaj deklarację typu jawnego, gdy jest częścią publicznego interfejsu API.
Nazewnictwo
Identyfikatory zawierają tylko litery i cyfry z zestawu ASCII oraz, w niewielkiej liczbie przypadków wymienionych poniżej, podkreślenia. W ten sposób każda prawidłowa nazwa identyfikatora jest dopasowywana do wyrażenia regularnego \w+
.
prefiksy specjalne (np. te występujące w przykładach);
name_
, mName
, s_name
i kName
nie są używane z wyjątkiem tych
właściwości kopii zapasowej (zobacz
Właściwości kopii zapasowej).
Nazwy pakietów
Nazwy pakietów są zapisane małymi literami, zawierają po prostu kolejne słowa połączone razem (bez znaków podkreślenia).
// Okay package com.example.deepspace // WRONG! package com.example.deepSpace // WRONG! package com.example.deep_space
Wpisz nazwy
Nazwy klas są pisane w zapisie PascalCase i zazwyczaj są rzeczownikami lub rzeczownikami
wyrażeniami. na przykład Character
lub ImmutableList
. Nazwy interfejsów mogą
mogą to być również rzeczowniki lub wyrażenia rzeczowniki (np. List
), ale
mogą to być czasami przymiotniki lub wyrażenia przymiotnikowe
(na przykład Readable
).
nazwy klas testowych zaczynają się od nazwy klasy, którą testują;
z końcówką Test
. Na przykład HashTest
lub
HashIntegrationTest
Nazwy funkcji
Nazwy funkcji zapisuje się wielkimi literami w przypadku znaków wielbłąda. Zwykle są to czasowniki lub wyrażenia. na przykład sendMessage
lub stop
.
W nazwach funkcji testowych mogą być używane podkreślenia, aby rozdzielić logiczne komponenty nazwy.
@Test fun pop_emptyStack() { // … }
Funkcje z adnotacjami @Composable
, które zwracają wartość Unit
, są typu PascalCased i nazwane jak rzeczowniki, tak jakby były typami.
@Composable fun NameTag(name: String) { // … }
Nazwy funkcji nie powinny zawierać spacji, ponieważ nie w każdym (na szczególną uwagę zasługuje funkcja, która nie jest w pełni obsługiwana w systemie Android).
// WRONG! fun `test every possible case`() {} // OK fun testEveryPossibleCase() {}
Stałe nazwy
W nazwach stałych używane są znaki UPPER_SNAKE_CASE: wszystkie wielkie litery, ze słowami rozdzielonymi podkreśleniami. Czym dokładnie jest stała?
Stałe to właściwości val
bez niestandardowej funkcji get
, których zawartość to
których nie można zmienić, a jego funkcje nie mają żadnych wykrywalnych skutków ubocznych. Ten
obejmuje typy stałe i stałe zbiory typów stałych
a także skalary i ciąg znaków, jeśli zostały oznaczone jako const
. Jeśli dowolna z instancji
ale nie jest stałą wartością. Zamierzam wyłącznie
To za mało.
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()
Nazwy te są zwykle rzeczownikami lub wyrażeniami rzeczownikami.
Wartości stałe można zdefiniować tylko wewnątrz elementu object
lub jako deklarację najwyższego poziomu. Wartości, które w przeciwnym razie spełniają wymagania
stała, ale zdefiniowana wewnątrz elementu class
, musi mieć nazwę niestałą.
Stałe, które są wartościami skalarnymi, muszą używać funkcji const
modyfikatorze.
Nazwy niestałe
Nazwy niestałe zapisuje się wielkimi literami wielka litera. Dotyczą one właściwości instancji, właściwości lokalnych i nazw parametrów.
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")
Nazwy te są zwykle rzeczownikami lub wyrażeniami rzeczownikami.
Właściwości kopii zapasowej
Gdy usługa pomocnicza jest wymagana, jej nazwa powinna być dokładnie taka sama jak nazwa nieruchomości oprócz tych, które są poprzedzone znakiem podkreślenia.
private var _table: Map<String, Int>? = null val table: Map<String, Int> get() { if (_table == null) { _table = HashMap() } return _table ?: throw AssertionError() }
Wpisz nazwy zmiennych
Każda zmienna typu ma nazwę w jednym z 2 sposobów:
- pojedyncza wielka litera, po której może następować znak
jedna cyfra (np.
E
,T
,X
,T2
) - Imię i nazwisko w formie użytej do oznaczenia zajęć z dopiskiem wielką literą
litera
T
(np.RequestT
,FooBarT
)
Wielbłąd wielkanocny
Czasami istnieje kilka rozsądnych sposobów zamiany angielskich wyrażeń na wielbłądy, na przykład przez akronimy lub nietypowe konstrukcje, takie jak „IPv6” lub „iOS”. Aby zwiększyć przewidywalność, użyj poniższego schematu.
Zacznijmy od formy prosowej imienia i nazwiska:
- Zmień wyrażenie na zwykłe ASCII i usuń wszelkie apostrofy. Na przykład „algorytm Mullera” może zostać zastąpiony przez „algorytm Mullera”.
- Podziel wynik na słowa, rozdzielając je spacjami i pozostałymi znakami interpunkcyjnymi (zwykle łącznikami). Zalecane: jeśli jakieś słowo ma już powszechny wygląd wielbłąda, podziel je na części składowe (np. „AdWords” stanie się „słowami reklamowymi”). Zwróć uwagę, że słowo takie jak „iOS” nie jest pisane jak wielka litera, jest sprzeczne z każdą konwencją, więc nie ma zastosowania.
- Teraz wszystko jest zapisane małymi literami (w tym akronimy), a potem wykonaj jedną z tych czynności:
- Pierwszy znak każdego wyrazu należy pisać wielką literą, aby uzyskać wielkość liter jak w przypadku poszczególnych słów.
- Wielkie litery w każdym słowie z wyjątkiem pierwszego znaku wielbłąda.
- Na koniec połącz wszystkie słowa w jeden identyfikator.
Zwróć uwagę, że wielkość liter w oryginalnych słowach jest niemal całkowicie ignorowana.
Formularz prose | Dobrze | Nieprawidłowo |
---|---|---|
„Żądanie XML HTTP” | XmlHttpRequest |
XMLHTTPRequest |
„nowy identyfikator klienta” | newCustomerId |
newCustomerID |
"wewnętrzny stoper" | innerStopwatch |
innerStopWatch |
„obsługuje IPv6 w iOS” | supportsIpv6OnIos |
supportsIPv6OnIOS |
„Importer YouTube” | YouTubeImporter |
YoutubeImporter * |
(* Dopuszczalne, ale niezalecane).
Dokumentacja
Formatowanie
Podstawowe formatowanie bloków KDoc przedstawiono w tym przykładzie:
/** * Multiple lines of KDoc text are written here, * wrapped normally… */ fun method(arg: String) { // … }
...lub w tym przykładzie z jednym wierszem:
/** An especially short bit of KDoc. */
Zawsze akceptowalna jest forma podstawowa. Format jednowierszowy może być
podmieniane, gdy cały blok KDoc (łącznie ze znacznikami komentarzy)
nie zmieści się w jednej linii. Należy pamiętać, że ma to zastosowanie tylko wówczas, gdy nie są zdefiniowane żadne wartości
blokuj tagi, takie jak @return
.
Akapity
jeden pusty wiersz, czyli wiersz zawierający tylko wyrównaną na początku gwiazdkę.
(*
) – pojawia się między akapitami i przed grupą tagów blokujących, jeśli występuje.
Blokuj tagi
Wszystkie używane standardowe „tagi blokowe” pojawiają się w określonej kolejności.
@constructor
, @receiver
, @param
, @property
, @return
@throws
, @see
i nigdy nie pojawiają się bez pustego opisu.
Jeśli tag blokowy nie mieści się w jednej linii,
są dodane wcięcie o 4 spacje od pozycji @
.
Fragment podsumowania
Każdy blok KDoc zaczyna się od krótkiego fragmentu podsumowania. Ten fragment jest bardzo ważne: jest to jedyna część tekstu, która pojawia się w określonych kontekstach, takich jak indeksy klas i metod.
Jest to fragment – wyrażenie rzeczownikowe lub wyrażenie czasownik, a nie całe zdanie.
Nie zaczyna się od „A `Foo` is a...
”,
lub „This method returns...
”,
nie musi też stanowić pełnego zdania imperatywnego,
„Save the record.
”. Jest on jednak pisany wielkimi literami,
przekreślone, jakby to było pełne zdanie.
Wykorzystanie
KDoc istnieje przynajmniej dla każdego typu public
,
a każdy element public
lub protected
tego typu,
z kilkoma wyjątkami opisanymi poniżej.
Wyjątek: funkcje wyjaśniające
Narzędzie KDoc jest opcjonalne w przypadku funkcji „prostych, oczywistych”, takich jak getFoo
i właściwości takich jak foo
.
Nie ma sensu cytować tego wyjątku, aby uzasadnić pominięcie stosownych
przydatne dla przeciętnego czytelnika. Na przykład w przypadku funkcji
funkcję o nazwie getCanonicalName
lub właściwości o nazwie canonicalName
,
nie pomijać dokumentacji (pod warunkiem, że doszło do
/** Returns the canonical name. */
), jeśli typowy czytnik może nie mieć
co to jest „nazwa kanoniczna” co znaczy!
Wyjątek: zastąpienia
Wartość KDoc nie zawsze jest dostępna w metodzie, która zastępuje metodę typu supertyp.