Úvod do jazyka Kotlin
1. Prehľad
V tomto výučbe sa pozrieme na Kotlin, nový jazyk vo svete JVM, a na niektoré z jeho základných funkcií, vrátane tried, dedenia, podmienených príkazov a cyklických konštrukcií.
Potom sa pozrieme na niektoré z hlavných funkcií, vďaka ktorým je Kotlin atraktívnym jazykom, vrátane nulovej bezpečnosti, dátových tried, rozširujúcich funkcií a String šablóny.
2. Maven závislosti
Ak chcete použiť Kotlin vo svojom projekte Maven, musíte do svojho programu pridať štandardnú knižnicu Kotlin pom.xml:
org.jetbrains.kotlin kotlin-stdlib 1.0.4
Ak chcete pridať podporu JUnit pre Kotlin, budete musieť zahrnúť aj nasledujúce závislosti:
org.jetbrains.kotlin kotlin-test-junit 1.0.4 test junit junit 4.12 test
Najnovšie verzie kotlin-stdlib, kotlin-test-junit a junit nájdete na serveri Maven Central.
Nakoniec budete musieť nakonfigurovať zdrojové adresáre a doplnok Kotlin, aby ste mohli zostaviť Maven:
$ {project.basedir} / src / main / kotlin $ {project.basedir} / src / test / kotlin kotlin-maven-plugin org.jetbrains.kotlin 1.0.4 kompilácia kompilácia test-kompilácia test-kompilácia
Najnovšiu verziu kotlin-maven-pluginu nájdete v Maven Central.
3. Základná syntax
Pozrime sa na základné stavebné prvky jazyka Kotlin.
Existuje určitá podobnosť s Javou (napr. Definovanie balíkov je rovnaké). Poďme sa pozrieť na rozdiely.
3.1. Definovanie funkcií
Definujme funkciu s dvoma parametrami Int Int návratový typ:
zábavná suma (a: Int, b: Int): Int {návrat a + b}
3.2. Definovanie miestnych premenných
Priradiť lokálnu premennú (iba na čítanie):
val a: Int = 1 val b = 1 val c: Int c = 1
Všimnite si tento typ premennej b je odvodený kompilátorom Kotlin. Mohli by sme tiež definovať premenlivé premenné:
var x = 5 x + = 1
4. Nepovinné polia
Kotlin má základnú syntax na definovanie poľa, ktoré by mohlo mať povolenú hodnotu Null (voliteľné). Ak chceme deklarovať, že typ poľa má povolenú hodnotu Null, musíme použiť typ s príponou s otáznikom:
val email: Reťazec?
Ak ste definovali pole s možnou hodnotou Null, je úplne platné priradiť a nulový k tomu:
val email: Reťazec? = null
To znamená, že v e-mailovom poli môže byť a nulový. Ak napíšeme:
val email: String = "value"
Potom musíme e-mailovému poľu priradiť hodnotu v rovnakom výpise, ktorý deklarujeme ako e-mail. Nemôže mať nulovú hodnotu. Vrátime sa späť ku Kotlinovi nulový bezpečnosť v ďalšej časti.
5. Triedy
Ukážme si, ako vytvoriť jednoduchú triedu pre správu konkrétnej kategórie produktu. Náš ItemManager trieda nižšie má predvolený konštruktor, ktorý vypĺňa dve polia - categoryId a dbConnection - a voliteľné e-mail lúka:
trieda ItemManager (val categoryId: String, val dbConnection: String) {var email = "" // ...}
To ItemManager (…) konštrukt vytvorí v našej triede konštruktor a dve polia: categoryId a dbConnection
Všimnite si, že náš konštruktér používa val kľúčové slovo pre jeho argumenty - to znamená, že zodpovedajúce polia budú konečné a nemenný. Keby sme použili var kľúčové slovo (ako sme to urobili pri definovaní súboru e-mail pole), potom by tieto polia boli zmeniteľné.
Vytvorme inštanciu ItemManageru pomocou predvoleného konštruktora:
ItemManager ("cat_id", "db: // pripojenie")
Mohli by sme zostrojiť ItemManager pomocou pomenovaných parametrov. Je veľmi užitočné, keď máte v tomto príklade funkciu, ktorá berie dva parametre rovnakého typu, napr. String, a nechcete zmiasť ich objednávku. Pomocou pomenovacích parametrov môžete explicitne napísať, ktorý parameter je priradený. V triede ItemManager existujú dve polia, categoryId a dbConnection takže na obidve je možné odkazovať pomocou pomenovaných parametrov:
ItemManager (categoryId = "catId", dbConnection = "db: // pripojenie")
Je to veľmi užitočné, keď potrebujeme funkcii odovzdať viac argumentov.
Ak potrebujete ďalšie konštruktory, definovali by ste ich pomocou konštruktér kľúčové slovo. Definujme iného konštruktora, ktorý tiež nastavuje e-mail lúka:
konštruktor (categoryId: String, dbConnection: String, email: String): this (categoryId, dbConnection) {this.email = email}
Upozorňujeme, že tento konštruktor vyvolá predvolený konštruktor, ktorý sme definovali vyššie, pred nastavením poľa e-mailu. A keďže sme si to už definovali categoryId a dbConnection byť nemenný pomocou val kľúčové slovo v predvolenom konštruktore, nemusíme opakovať val kľúčové slovo v dodatočnom konštruktore.
Teraz vytvorme inštanciu pomocou dodatočného konštruktora:
ItemManager ("cat_id", "db: // pripojenie", "[chránené e-mailom]")
Ak chcete definovať inštančnú metódu na ItemManager, urobili by ste to pomocou zábava kľúčové slovo:
fun isFromSpecificCategory (catId: String): Boolean {return categoryId == catId}
6. Dedenie
Predvolene sú Kotlinove triedy uzavreté pre rozšírenie - ekvivalent označenej triedy konečné v Jave.
Na určenie, že je trieda otvorená pre rozšírenie, by ste použili otvorené kľúčové slovo pri definovaní triedy.
Definujme si Položka trieda, ktorá je otvorená pre rozšírenie:
položka otvorenej triedy (val id: String, val name: String = "unknown_name") {open fun getIdOfItem (): String {return id}}
Upozorňujeme, že sme tiež označili getIdOfItem () metóda ako otvorená. To umožňuje jeho prepísanie.
Teraz poďme rozšíriť Položka triedy a prepísať getIdOfItem () metóda:
trieda ItemWithCategory (id: String, názov: String, val categoryId: String): Item (id, name) {override fun getIdOfItem (): String {return id + name}}
7. Podmienené vyhlásenia
In Kotlin, podmienečné vyhlásenie ak je ekvivalent funkcie, ktorá vracia určitú hodnotu. Pozrime sa na príklad:
fun makeAnalyisOfCategory (catId: String): Unit {val result = if (catId == "100") "Yes" else "No" println (result)}
Na tomto príklade vidíme, že ak kat sa rovná „100“ podmieneného bloku vráti „Áno“, inak vráti „Nie“. Vrátená hodnota bude priradená k výsledok.
Mohli by ste vytvoriť normálu ak–inak blok:
číslo valca = 2 if (číslo 10) {println ("číslo je väčšie ako 10")}
Kotlin má tiež veľmi užitočné kedy príkaz, ktorý funguje ako rozšírený príkaz switch:
val name = "John" when (name) {"John" -> println ("Hi man") "Alice" -> println ("Hi lady")}
8. Zbierky
V Kotline existujú dva typy zbierok: premenlivé a nemenné. Keď vytvoríme nemennú zbierku, znamená to, že je iba na čítanie:
val položky = listOf (1, 2, 3, 4)
V tomto zozname nie je žiadny prvok funkcie pridania.
Ak chceme vytvoriť premenlivý zoznam, ktorý by sa dal zmeniť, musíme použiť mutableListOf () metóda:
val rwList = mutableListOf (1, 2, 3) rwList.add (5)
Meniteľný zoznam má pridať () metódu, aby sme k nej mohli pridať prvok. Existuje tiež ekvivalentná metóda ako iné typy zbierok: mutableMapOf (), mapOf (), setOf (), mutableSetOf ()
9. Výnimky
Mechanizmus spracovania výnimiek je veľmi podobný ako v Jave.
Všetky triedy výnimiek sa rozširujú Hoditeľné. Výnimka musí obsahovať správu, stacktrace a voliteľnú príčinu. Každá výnimka v Kotline nie je začiarknutá, čo znamená, že kompilátor nás nenúti ich chytiť.
Na vyhodenie objektu výnimky musíme použiť výraz throw:
throw Exception ("správa")
Spracovanie výnimky sa vykonáva pomocou skúste ... chytiť blok (konečne voliteľné):
skúste {} chytiť (e: SomeException) {} konečne {}
10. Lambdas
V Kotline by sme mohli definovať funkcie lambda a odovzdať ich ako argumenty iným funkciám.
Pozrime sa, ako definovať jednoduchú lambdu:
val sumLambda = {a: Int, b: Int -> a + b}
Definovali sme sumLambda funkcia, ktorá berie dva argumenty typu Int ako argument a vráti sa Int.
Mohli by sme okolo obísť lambdu:
@Test fun givenListOfNumber_whenDoingOperationsUsingLambda_shouldReturnProperResult () {// given val listOfNumbers = listOf (1, 2, 3) // when val sum = listOfNumbers.reduce {a, b -> a + b} // then assertEquals (6, sum)}
11. Smyčkové konštrukty
V Kotline sa opakovanie v zbierkach dalo robiť pomocou štandardu pre..v konštruovať:
čísla valcov = arrayOf ("prvý", "druhý", "tretí", "štvrtý")
pre (n v číslach) {println (n)}
Ak chceme iterovať v rozsahu celých čísel, mohli by sme použiť konštrukt rozsahu:
pre (i v 2..9 kroku 2) {println (i)}
Upozorňujeme, že rozsah v príklade vyššie je na oboch stranách. The krok parameter je voliteľný a je ekvivalentom zvýšenia počítadla dvakrát v každej iterácii. Výstup bude nasledujúci:
2 4 6 8
Mohli by sme použiť a rangeTo () funkcia, ktorá je definovaná na Int triedy nasledujúcim spôsobom:
1.rangeTo (10) .map {it * 2}
Výsledok bude obsahovať (všimnite si, že rangeTo () vrátane):
[2, 4, 6, 8, 10, 12, 14, 16, 18, 20]
12. Nulová bezpečnosť
Pozrime sa na jednu z kľúčových vlastností Kotlin - nulovú bezpečnosť, ktorá je zabudovaná do jazyka. Na ilustráciu, prečo je to užitočné, vytvoríme jednoduchú službu, ktorá vráti znak Položka objekt:
trieda ItemService {fun findItemNameForId (id: String): Item? {val itemId = UUID.randomUUID (). toString () vrátiť položku (itemId, "name- $ itemId"); }}
Je dôležité si uvedomiť, že je vrátený typ tejto metódy. Je to predmet, za ktorým nasleduje otáznik. Je to konštrukt z jazyka Kotlin, čo znamená Položka vrátené z tejto metódy by mohli mať hodnotu null. Tento prípad musíme vyriešiť v čase kompilácie a rozhodnúť sa, čo chceme s týmto objektom urobiť (je to viac-menej ekvivalentné Java 8 Voliteľné typu).
Ak má podpis metódy typ bez otáznika:
fun findItemNameForId (id: String): Položka
potom volanie kódu nebude musieť zvládnuť nulový prípad, pretože je zaručený kompilátorom a jazykom Kotlin, že vrátený objekt nemôže byť nulový.
Inak, ak existuje metóda s možnou hodnotou Null odovzdaná metóde a daný prípad sa nespracuje, nebude sa kompilovať.
Napíšme testovací prípad pre bezpečnosť typu Kotlin:
val id = "item_id" val itemService = ItemService () val výsledok = itemService.findItemNameForId (id) assertNotNull (výsledok? .let {it -> it.id}) assertNotNull (výsledok !!. id)
Vidíme to tu po vykonaní metódy findItemNameForId (), vrátený typ je Kotlin Nullable. Prístup do poľa tohto objektu (id), musíme daný prípad vyriešiť v čase kompilácie. Metóda nech () sa vykoná, iba ak je výsledok nulový. Jad pole je prístupné vo vnútri funkcie lambda, pretože je nulové bezpečné.
Ďalším spôsobom, ako získať prístup k uvedenému poli s povolenou hodnotou null, je použitie operátora Kotlin !!. Je to ekvivalentné s:
if (výsledok == null) {throwNpe (); } vrátiť výsledok;
Kotlin skontroluje, či je tento objekt a nulový ak ano tak vyhodi a NullPointerException, inak vráti správny objekt. Funkcia throwNpe () je Kotlinova interna funkcia.
13. Dátové triedy
Veľmi pekným jazykovým konštruktom, ktorý sa dá nájsť v Kotline, sú dátové triedy (je to ekvivalent „triedy prípadov“ z jazyka Scala). Účelom týchto tried je uchovávať iba údaje. V našom príklade sme mali Položka trieda, ktorá obsahuje iba údaje:
položka dátovej triedy (val id: String, val názov: String)
Kompilátor pre nás vytvorí metódy hashCode (), rovná sa ()a natiahnuť(). Osvedčeným postupom je urobiť dátové triedy nemennými pomocou a val kľúčové slovo. Dátové triedy môžu mať predvolené hodnoty polí:
položka dátovej triedy (val id: String, val name: String = "unknown_name")
Vidíme to názov pole má predvolenú hodnotu „unknown_name“.
14. Rozširujúce funkcie
Predpokladajme, že máme triedu, ktorá je súčasťou knižnice tretích strán, ale chceme ju rozšíriť o ďalšiu metódu. Kotlin nám to umožňuje pomocou funkcií rozšírenia.
Uvažujme o príklade, v ktorom máme zoznam prvkov a chceme z neho zobrať náhodný prvok. Chceme pridať novú funkciu random () do 3. strany Zoznam trieda.
Takto to vyzerá v Kotline:
zábava List.random (): T? {if (this.isEmpty ()) return null return get (ThreadLocalRandom.current (). nextInt (count ()))}
Najdôležitejšie je všimnúť si tu podpis metódy. Pred touto metódou je uvedený názov triedy, do ktorej pridávame túto metódu navyše.
Vo vnútri metódy rozšírenia pracujeme na rozsahu zoznamu, a preto používame toto umožnil použitie prístupu k metódam inštancie zoznamu ako je prázdny() alebo count (). Potom sme schopní zavolať random () metóda na ľubovoľnom zozname, ktorý je v tomto rozsahu:
zábava getRandomElementOfList (zoznam: zoznam): T? {návrat list.random ()}
Vytvorili sme metódu, ktorá zaberie zoznam a potom vykoná funkciu vlastnej prípony random () ktorý bol predtým definovaný. Napíšme testovací prípad pre našu novú funkciu:
val elements = listOf ("a", "b", "c") val result = ListExtension (). getRandomElementOfList (elements) assertTrue (elements.contains (result))
Možnosť definovania funkcií, ktoré „rozširujú“ triedy tretích strán, je veľmi výkonná vlastnosť, ktorá umožňuje, aby bol náš kód stručnejší a čitateľnejší.
15. Šablóny reťazcov
Veľmi príjemnou vlastnosťou jazyka Kotlin je možnosť používať šablóny pre Strings. Je to veľmi užitočné, pretože nemusíme spájať Strings ručne:
val firstName = "Tom" val secondName = "Mary" val concatOfNames = "$ firstName + $ secondName" val sum = "štyri: $ {2 + 2}"
Môžeme tiež vyhodnotiť výraz vo vnútri ${} blok:
val itemManager = ItemManager ("cat_id", "db: // pripojenie") val result = "výsledok funkcie: $ {itemManager.isFromSpecificCategory (" 1 ")}"
16. Interoperabilita Kotlin / Java
Spolupráca Kotlin - Java je bezproblémová. Predpokladajme, že máme triedu Java s metódou, ktorá funguje ďalej Reťazec:
trieda StringUtils {public static String toUpperCase (názov reťazca) {návratové meno.toUpperCase (); }}
Teraz chceme spustiť tento kód z našej triedy Kotlin. Potrebujeme iba importovať túto triedu a bez problémov by sme mohli spustiť metódu java z Kotlin:
val name = "tom" val res = StringUtils.toUpperCase (name) assertEquals (res, "TOM")
Ako vidíme, použili sme metódu java z kódu Kotlin.
Volanie kódu Kotlin z jazyka Java je tiež veľmi jednoduché. Definujme jednoduchú funkciu Kotlin:
trieda MathematicsOperations {fun addTwoNumbers (a: Int, b: Int): Int {return a + b}}
Vykonávanie addTwoNumbers () z Java kódu je veľmi jednoduché:
int res = new MathematicsOperations (). addTwoNumbers (2, 4); assertEquals (6, res);
Vidíme, že volanie na Kotlinov kód bolo pre nás transparentné.
Keď definujeme metódu v jave, tento návratový typ je a neplatný, v Kotline bude vrátená hodnota a Jednotka typu.
V jazyku Java existujú niektoré špeciálne identifikátory ( je, objekt, v, ..) že pri ich použití v kóde Kotlin je potrebné uniknúť. Mohli by sme napríklad definovať metódu, ktorá má názov objekt () ale musíme pamätať na to, aby ste tomuto názvu unikli, pretože ide o špeciálny identifikátor v jave:
fun `object` (): Reťazec {return" toto je objekt "}
Potom by sme mohli vykonať túto metódu:
`objekt` ()
17. Záver
Tento článok predstavuje úvod do jazyka Kotlin a jeho kľúčové vlastnosti. Začína sa to zavedením jednoduchých konceptov, ako sú slučky, podmienené príkazy a definovanie tried. Potom sa zobrazí niekoľko pokročilejších funkcií, ako sú funkcie rozšírenia a nulová bezpečnosť.
Implementáciu všetkých týchto príkladov a útržkov kódu nájdete v projekte GitHub.