Kotlin, ktorý bol oficiálne uvedený v roku 2016, v posledných rokoch priťahoval veľkú pozornosť, najmä preto, že Google oznámil podporu Kotlin ako alternatívy k Jave na platformách Android. S nedávno oznámeným rozhodnutím, aby sa Kotlin stal preferovaným jazykom pre Android, si možno hovoríte, či je čas začať sa učiť nový programovací jazyk. V takom prípade by vám tento článok mohol pomôcť rozhodnúť sa.
História vydania Kotlina
Kotlin bol oznámený v roku 2011, ale prvé stabilné vydanie, verzia 1.0, sa objavilo až v roku 2016. Jazyk je bezplatný a otvorený zdroj, ktorý vyvinula spoločnosť JetBrains s vedúcim jazykovým dizajnérom Andrey Breslav. Kotlin 1.3.40 bol vydaný v júni 2019.
O Kotlinovi
Kotlin je moderný, staticky napísaný programovací jazyk, ktorý obsahuje objektovo aj funkčne konštruované programovanie. Zameriava sa na niekoľko platforiem vrátane JVM a je plne interoperabilný s programom Java. V mnohých ohľadoch je Kotlin to, ako by mohla vyzerať Java, keby bola navrhnutá dnes. V tomto článku predstavujem osem funkcií Kotlinu, o ktorých verím, že ich vývojári Java budú nadšení.
- Čistá a kompaktná syntax
- Systém jedného typu (takmer)
- Nulová bezpečnosť
- Funkcie a funkčné programovanie
- Dátové triedy
- Prípony
- Preťaženie obsluhy
- Predmety najvyššej úrovne a vzor Singleton
Ahoj, svet! Kotlin verzus Java
Zoznam 1 zobrazuje povinné „Ahoj, svet!“ funkcia napísaná v Kotline.
Zoznam 1. „Ahoj, svet!“ v Kotline
fun main () {println ("Ahoj, svet!")}
Tento príklad je jednoduchý, takže odhaľuje kľúčové rozdiely od Javy.
hlavný
je funkcia najvyššej úrovne; to znamená, že funkcie Kotlin nemusia byť vnorené do triedy.- Nie sú k dispozícii žiadne
verejná statická
modifikátory. Zatiaľ čo Kotlin má modifikátory viditeľnosti, predvolená hodnota jeverejné
a možno ich vynechať. Kotlin tiež nepodporujestatický
modifikátor, ale v tomto prípade to nie je potrebné, pretožehlavný
je funkcia najvyššej úrovne. - Od verzie Kotlin 1.3 je parameter poľa reťazcov pre
hlavný
sa nevyžaduje a ak sa nepoužíva, môže sa vynechať. V prípade potreby by bol vyhlásený zaargs: Pole
. - Pre funkciu nie je zadaný žiadny návratový typ. Kde sa používa Java
neplatný
, Používa KotlinJednotka
, a ak je návratový typ funkcieJednotka
, možno vynechať. - V tejto funkcii nie sú zadané bodkočiarky. V Kotline sú bodkočiarky voliteľné, a preto sú zalomenia riadkov významné.
To je prehľad, ale je potrebné sa dozvedieť oveľa viac o tom, ako sa Kotlin líši od Javy a v mnohých prípadoch ju vylepšuje.
1. Čistšia a kompaktnejšia syntax
Java je často kritizovaná za to, že je príliš podrobná, ale určitá výrečnosť môže byť vaším priateľom, najmä ak robí zdrojový kód zrozumiteľnejším. Výzvou v jazykovom dizajne je znížiť výrečnosť pri zachovaní jasnosti a myslím si, že Kotlin ide dlhou cestou k splneniu tejto výzvy.
Ako ste videli v zozname 1, Kotlin nevyžaduje bodkočiarky a umožňuje vynechať návratový typ pre Jednotka
funkcie. Uvažujme o niekoľkých ďalších funkciách, vďaka ktorým je Kotlin čistejšou a kompaktnejšou alternatívou k Jave.
Odvodzovanie typu
V Kotline môžete deklarovať premennú ako var x: Int = 5
, alebo môžete použiť kratšiu, ale rovnako prehľadnú verziu var x = 5
. (Zatiaľ čo Java teraz podporuje var
deklarácie, táto funkcia sa objavila až v Jave 10, dlho potom, čo sa táto funkcia objavila v Kotline.)
Kotlin tiež má val
vyhlásenia pre premenné iba na čítanie, ktoré sú analogické s premennými Javy, ktoré boli deklarované ako konečné
, čo znamená, že premennú nemožno priradiť znova. Výpis 2 uvádza príklad.
Výpis 2. Premenné iba na čítanie v Kotline
val x = 5 ... x = 6 // CHYBA: NESPRACUJE SA
Vlastnosti verzus polia
Tam, kde má Java polia, má Kotlin vlastnosti. Vlastnosti sú deklarované a pristupuje sa k nim podobným spôsobom ako k verejným poliam v Jave, ale Kotlin poskytuje predvolené implementácie funkcií prístupového / mutačného nástroja pre vlastnosti; to znamená, že poskytuje Kotlin dostať ()
funkcie pre val
vlastnosti a oboje dostať ()
a sada ()
funkcie pre var
vlastnosti. Prispôsobené verzie servera dostať ()
a sada ()
môžu byť implementované v prípade potreby.
Väčšina nehnuteľností v Kotline bude mať podporné polia, ale je možné definovať a vypočítaná vlastnosť, čo je v podstate a dostať ()
funkcia bez podporného poľa. Napríklad trieda predstavujúca osobu môže mať vlastníctvo pre dátum narodenia
a vypočítaná vlastnosť pre Vek
.
Predvolené verzus explicitné importy
Java implicitne importuje triedy definované v balíku java.lang
, ale všetky ostatné triedy musia byť explicitne importované. Výsledkom je, že veľa zdrojových súborov Java začína importom tried kolekcie z java.util
, I / O triedy z java.io
a tak ďalej. Štandardne Kotlin implicitne importuje kotlin. *
, čo je zhruba obdoba importu Java java.lang. *
, ale Kotlin aj dováža kotlin.io. *
, kotlin.collections. *
a triedy z niekoľkých ďalších balíkov. Z tohto dôvodu zdrojové súbory Kotlin zvyčajne vyžadujú menej explicitných importov ako zdrojové súbory Java, najmä pre triedy, ktoré používajú kolekcie a / alebo štandardné I / O.
Pre konštruktérov nie je potrebné volať „nové“
V Kotline kľúčové slovo Nový
nie je potrebný na vytvorenie nového objektu. Ak chcete zavolať konštruktéra, stačí použiť názov triedy so zátvorkami. Kód Java
Študent s = nový Študent (...); // alebo var s = new Student (...);
by sa dal v Kotline napísať takto:
var s = Študent (...)
Šnúrkové šablóny
Struny môžu obsahovať šablónové výrazy, čo sú výrazy, ktoré sa vyhodnocujú s výsledkami vloženými do reťazca. Výraz šablóny sa začína znakom dolára ($) a skladá sa buď z jednoduchého názvu, alebo z ľubovoľného výrazu v zložených zátvorkách. Šablóny reťazcov môžu skrátiť výrazy reťazcov znížením potreby explicitného zreťazenia reťazcov. Napríklad nasledujúci kód Java
println ("Meno:" + meno + ", Oddelenie:" + odd.);
by sa dal nahradiť kratším, ale ekvivalentným Kotlinovým kódom.
println ("Meno: $ meno, Oddelenie: $ odd")
Rozširuje a implementuje
Programátori Java vedia, že trieda môže predĺžiť
iná trieda a realizovať
jedno alebo viac rozhraní. V Kotline neexistuje žiadny syntaktický rozdiel medzi týmito dvoma podobnými konceptmi; Kotlin pre oba používa dvojbodku. Napríklad kód Java
verejná trieda Študent rozširuje Osobné náradie Porovnateľné
by bolo jednoduchšie napísané v Kotline takto:
trieda Študent: Osoba, porovnateľný
Žiadne začiarknuté výnimky
Kotlin podporuje výnimky podobným spôsobom ako Java s jedným veľkým rozdielom - Kotlin nemá skontrolované výnimky. Aj keď boli dobre zamýšľané, kontrolované výnimky Java boli všeobecne kritizované. Stále môžeš hodiť
a chytiť
výnimky, ale kompilátor Kotlin vás nenúti chytiť ani jednu z nich.
Deštrukturalizácia
Rozmýšľať o deštruktívne ako jednoduchý spôsob rozbitia objektu na jeho základné časti. Deklarácia deštrukcie vytvorí viac premenných naraz. Zoznam 3 uvedený nižšie poskytuje niekoľko príkladov. V prvom príklade predpokladajme túto premennú študent
je inštancia triedy Študent
, ktorý je definovaný v zozname 12 nižšie. Druhý príklad je prevzatý priamo z dokumentácie Kotlin.
Zoznam 3. Príklady deštrukturalizácie
val (_, lName, fName) = študent // extrahovať meno a priezvisko zo študentského objektu // podčiarkovník znamená, že nepotrebujeme student.id pre ((kľúč, hodnota) v mape) {// urob niečo s kľúčom a hodnota}
výroky a výrazy „ak“
V Kotline ak
možno použiť na riadiaci tok ako v prostredí Java, ale dá sa použiť aj ako výraz. Tajomný ternárny operátor Java (?:
) je nahradený jasnejším, ale o niečo dlhším ak
výraz. Napríklad kód Java
dvojnásobok max = x> = y? x: y
bude napísané v Kotline takto:
val max = if (x> = y), potom x else y
Kotlin je v tomto prípade o niečo podrobnejší ako Java, ale syntax je pravdepodobne čitateľnejšia.
„keď“ nahradí „prepínač“
Moja najmenej obľúbená štruktúra riadenia v jazykoch podobných jazyku C je prepínač
vyhlásenie. Kotlin nahrádza prepínač
vyhlásenie s a kedy
vyhlásenie. Výpis 4 je prevzatý priamo z dokumentácie Kotlin. Všimni si prestávka
vyhlásenia nie sú povinné a môžete ľahko zahrnúť rozsahy hodnôt.
Výpis 4. Výrok „keď“ v Kotline
when (x) {in 1..10 -> print ("x is in the range") in validNumbers -> print ("x is valid")! in 10..20 -> print ("x is outside the range ") else -> print (" nič z vyššie uvedeného ")}
Skúste zoznam 4 prepísať ako tradičný jazyk C / Java prepínač
vyhlásenie, a získate predstavu o tom, ako lepšie sa máme s Kotlinovou lepšie kedy
vyhlásenie. Tiež, podobné ak
, kedy
možno použiť ako výraz. V takom prípade sa hodnota spokojnej vetvy stane hodnotou celkového výrazu.
Prepínanie výrazov v prostredí Java
Java 12 predstavila výrazy prepínačov. Podobne ako u Kotlina kedy
„Prepínacie výrazy Java nevyžadujú prestávka
výroky a môžu sa použiť ako výroky alebo výrazy. Viac informácií o výrazoch prepínania v jazyku Java nájdete v časti „Opakovanie, prepínanie alebo prestávka? Rozhodovanie a opakovanie pomocou príkazov“.
2. Systém jedného typu (takmer)
Java má dva samostatné systémy typov, primitívne typy a referenčné typy (alias objekty, objekty). Existuje veľa dôvodov, prečo Java obsahuje dva systémy samostatného typu. To vlastne nie je pravda. Ako je uvedené v mojom článku Prípad zachovania primitívov v Jave, pre primitívne typy existuje skutočne jediný dôvod - výkon. Podobne ako Scala, Kotlin má iba jeden typový systém v tom, že v podstate nie je žiadny rozdiel medzi primitívnymi typmi a referenčnými typmi v Kotline. Kotlin používa primitívne typy, pokiaľ je to možné, ale v prípade potreby použije objekty.
Prečo je teda výhrada „takmer“? Pretože Kotlin má aj špecializované triedy, ktoré reprezentujú polia primitívnych typov bez réžie autoboxingu: IntArray
, DoubleArray
a tak ďalej. Na JVM DoubleArray
je implementovaný ako dvojitý []
. Má pomocou DoubleArray
naozaj urobiť rozdiel? Pozrime sa.
Benchmark 1: Násobenie matíc
Pri príprave prípadu pre primitívy Java som ukázal niekoľko porovnávacích výsledkov porovnávajúcich primitívy Java, triedy Java wrapper a podobný kód v iných jazykoch. Jedným z benchmarkov bolo jednoduché násobenie matíc. Pre porovnanie výkonu Kotlin s Javou som vytvoril pre Kotlin dve implementácie násobenia matíc, jednu s použitím Pole
a jeden pomocou Pole
. Výpis 5 zobrazuje implementáciu Kotlin pomocou Pole
.
Výpis 5. Násobenie matíc v Kotline
zábavné násobenie (a: Array, b: Array): Array {if (! checkArgs (a, b)) throw Exception ("Matice nie sú kompatibilné s násobením") val nRows = a.size val nCols = b [0]. size val result = Array (nRows, {_ -> DoubleArray (nCols, {_ -> 0,0})}) for (rowNum in 0 until nRows) {for (colNum in 0 until nCols) {var sum = 0.0 for (i v 0 do a [0] .size) sum + = a [rowNum] [i] * b [i] [colNum] výsledok [rowNum] [colNum] = sum}} návratový výsledok}
Ďalej som porovnal výkon dvoch verzií Kotlin s výkonom v Java dvojitý
a Java s Dvojitý
, prevádzkujúci všetky štyri štandardy na mojom súčasnom notebooku. Pretože pri spustení každého benchmarku existuje malé množstvo „šumu“, spustil som všetky verzie trikrát a spriemeroval som výsledky, ktoré sú zhrnuté v tabuľke 1.
Tabuľka 1. Runtime výkon porovnávacieho testu násobenia matíc
Java ( | Java ( | Kotlin ( | Kotlin ( |
7.30 | 29.83 | 6.81 | 15.82 |
Tieto výsledky ma trochu prekvapili a nakreslím si dva stánky so sebou. Po prvé, výkon Kotlin pomocou DoubleArray
je jednoznačne lepší ako výkon Kotlina Pole
, čo je jednoznačne lepšie ako v prípade Java pomocou triedy wrapper Dvojitý
. A za druhé, výkon Kotlin pomocou DoubleArray
je porovnateľný s - a v tomto príklade o niečo lepším ako - výkonom Java pomocou primitívneho typu dvojitý
.
Je zrejmé, že Kotlin odviedol skvelú prácu pri optimalizácii potreby systémov samostatného typu - s výnimkou potreby používať triedy ako DoubleArray
namiesto Pole
.
Benchmark 2: SciMark 2.0
Môj článok o primitívnych prostriedkoch obsahoval aj druhý, vedeckejší benchmark známy ako SciMark 2.0, čo je benchmark Java pre vedecké a numerické výpočty dostupný od Národného ústavu pre štandardy a technológiu (NIST). Benchmark SciMark meria výkon niekoľkých výpočtových rutín a približné hlási zložené skóre Mflops (milióny operácií s pohyblivou rádovou čiarkou za sekundu). Pre túto referenčnú hodnotu sú teda lepšie väčšie čísla.
S pomocou IntelliJ IDEA som konvertoval Java verziu benchmarku SciMark na Kotlin. IntelliJ IDEA sa automaticky prevedie dvojitý []
a int []
v Jave do DoubleArray
a IntArray
v Kotline. Potom som porovnal verziu Java pomocou primitívov s verziou Kotlin pomocou DoubleArray
a IntArray
. Rovnako ako predtým som obe verzie spustil trikrát a spriemeroval som výsledky, ktoré sú zhrnuté v tabuľke 2. Tabuľka opäť ukazuje zhruba porovnateľné výsledky.
Tabuľka 2. Runtime výkon testovacej hodnoty SciMark
Java | Kotlin |
1818.22 | 1815.78 |