Virallisesti julkaistu vuonna 2016, Kotlin on herättänyt paljon huomiota viime vuosina, varsinkin kun Google ilmoitti tukevansa Kotlinia vaihtoehtona Javalle Android-alustoilla. Äskettäin ilmoitetun päätöksen kanssa tehdä Kotlinista ensisijainen kieli Androidille, saatat miettiä, onko aika aloittaa uuden ohjelmointikielen oppiminen. Jos näin on, tämä artikkeli voi auttaa sinua päättämään.
Kotlinin julkaisuhistoria
Kotlin ilmoitettiin vuonna 2011, mutta ensimmäinen vakaa julkaisu, versio 1.0, ilmestyi vasta vuonna 2016. Kieli on ilmainen ja avoin lähdekoodin, jonka on kehittänyt JetBrains ja sen johtavana kielisuunnittelijana toimii Andrey Breslav. Kotlin 1.3.40 julkaistiin kesäkuussa 2019.
Tietoja Kotlinista
Kotlin on moderni, staattisesti kirjoitettu ohjelmointikieli, joka sisältää sekä olio- että toiminnallisia ohjelmointirakenteita. Se on kohdistettu useille alustoille, mukaan lukien JVM, ja se on täysin yhteensopiva Java: n kanssa. Monilla tavoin Kotlin on se, miltä Java saattaa näyttää, jos se suunnitellaan tänään. Tässä artikkelissa esitän Kotlinin kahdeksan ominaisuutta, joiden uskon Java-kehittäjien olevan innoissaan löytämisessä.
- Puhdas, kompakti syntaksi
- Yhden tyyppinen järjestelmä (melkein)
- Ei mitään turvallisuutta
- Toiminnot ja toiminnallinen ohjelmointi
- Dataluokat
- Laajennukset
- Kuljettajan ylikuormitus
- Ylätason objektit ja Singleton-kuvio
Hei maailma! Kotlin vs. Java
Luettelossa 1 näkyy pakollinen "Hei, maailma!" Kotlinissa kirjoitettu toiminto.
Listaus 1. "Hei, maailma!" Kotlinissa
hauska pää () {println ("Hei maailma!")}
Niin yksinkertainen kuin se onkin, tämä esimerkki paljastaa tärkeimmät erot Java: sta.
tärkein
on ylätason toiminto; toisin sanoen Kotlin-toimintoja ei tarvitse sijoittaa luokan sisällä.- Ei ole olemassa
julkinen staattinen
muokkaajat. Vaikka Kotlinilla on näkyvyyden muokkaajia, oletus onjulkinen
ja voidaan jättää pois. Kotlin ei myöskään tuestaattinen
muokkaaja, mutta sitä ei tarvita tässä tapauksessa, koskatärkein
on ylätason toiminto. - Kotlin 1.3: n jälkeen merkkijonojen matriisi-parametri
tärkein
ei vaadita, ja se voidaan jättää pois, jos sitä ei käytetä. Tarvittaessa se ilmoitetaanargs: Taulukko
. - Funktiolle ei ole määritetty palautustyyppiä. Missä Java käyttää
mitätön
, Kotlin käyttääYksikkö
ja jos funktion palautustyyppi onYksikkö
, se voidaan jättää pois. - Tässä toiminnossa ei ole puolipisteitä. Kotlinissa puolipisteet ovat valinnaisia, ja siksi rivinvaihdot ovat merkittäviä.
Se on yleiskatsaus, mutta on paljon enemmän opittavaa siitä, miten Kotlin eroaa Javasta ja monissa tapauksissa parantaa sitä.
1. Puhtaampi, kompaktimpi syntaksia
Jaavaa kritisoidaan usein liian sanallisuudesta, mutta jotkut sanat voivat olla ystäväsi, varsinkin jos se tekee lähdekoodista ymmärrettävämmän. Kielisuunnittelun haasteena on vähentää sanallisuutta samalla kun säilytetään selkeys, ja mielestäni Kotlin kulkee paljon eteenpäin tähän haasteeseen vastaamiseksi.
Kuten näet luettelosta 1, Kotlin ei vaadi puolipisteitä, ja se sallii palautustyypin jättämisen Yksikkö
toimintoja. Tarkastellaan muutamia muita ominaisuuksia, jotka auttavat tekemään Kotlinista puhtaamman ja kompaktimman vaihtoehdon Java-ohjelmalle.
Tyyppinen päättely
Kotlinissa voit ilmoittaa muuttujan muodossa var x: Int = 5
, tai voit käyttää lyhyempää mutta yhtä selkeää versiota var x = 5
. (Vaikka Java tukee nyt var
ilmoituksia, tämä ominaisuus ilmestyi vasta Java 10: ssä kauan sen jälkeen, kun ominaisuus oli ilmestynyt Kotlinissa.)
Kotlinilla on myös val
vain luku -muuttujien ilmoitukset, jotka ovat analogisia Java-muuttujien kanssa lopullinen
, eli muuttujaa ei voida määrittää uudelleen. Listaus 2 antaa esimerkin.
Listaus 2. Vain luku -muuttujat Kotlinissa
val x = 5 ... x = 6 // VIRHE: EI KOOSTA
Ominaisuudet vs. kentät
Jos Javalla on kenttiä, Kotlinilla on ominaisuuksia. Ominaisuudet ilmoitetaan ja niihin pääsee samalla tavalla kuin Javan julkiset kentät, mutta Kotlin tarjoaa oletusasetukset lisäominaisuus- / mutatointitoiminnoille ominaisuuksille; eli Kotlin tarjoaa saada()
toiminnot val
ominaisuudet ja molemmat saada()
ja aseta()
toiminnot var
ominaisuudet. Räätälöidyt versiot saada()
ja aseta()
voidaan toteuttaa tarvittaessa.
Suurimmalla osalla Kotlinin kiinteistöistä on taustakentät, mutta on mahdollista määrittää a laskettu ominaisuus, joka on olennaisesti a saada()
toiminto ilman taustakenttää. Esimerkiksi henkilöä edustavalla luokalla voi olla ominaisuus syntymäaika
ja laskettu ominaisuus ikä
.
Oletus vs. nimenomainen tuonti
Java tuo implisiittisesti paketissa määriteltyjä luokkia java.lang
, mutta kaikki muut luokat on nimenomaisesti tuotava. Tämän seurauksena monet Java-lähdetiedostot alkavat tuoda kokoeluluokat java.util
, I / O-luokat alkaen java.io
, ja niin edelleen. Kotlin tuo oletusarvoisesti epäsuorasti kotlin. *
, joka on suunnilleen analoginen Java-tuonnin kanssa java.lang. *
, mutta myös Kotlin tuo kotlin.io. *
, kotlin. kokoelmat. *
ja luokkia useista muista paketeista. Tämän vuoksi Kotlinin lähdetiedostot vaativat tavallisesti vähemmän nimenomaista tuontia kuin Java-lähdetiedostot, erityisesti luokille, jotka käyttävät kokoelmia ja / tai tavallisia I / O-tiedostoja.
Rakentajille ei vaadita "uutta"
Kotlinissa avainsana Uusi
ei tarvita uuden objektin luomiseen. Soittaaksesi rakentajalle, käytä vain luokan nimeä sulkeissa. Java-koodi
Opiskelija s = uusi opiskelija (...); // tai var s = uusi opiskelija (...);
voitaisiin kirjoittaa Kotlinissa seuraavasti:
var s = Opiskelija (...)
Merkkijonomallit
Merkkijonot voivat sisältää mallilausekkeet, jotka ovat lausekkeita, jotka arvioidaan merkkijonoon lisättyjen tulosten kanssa. Mallilauseke alkaa dollarin merkillä ($) ja koostuu joko yksinkertaisesta nimestä tai mielivaltaisesta lausekkeesta. Merkkijonomallit voivat lyhentää merkkijonolausekkeita vähentämällä nimenomaisen merkkijonon ketjutuksen tarvetta. Esimerkiksi seuraava Java-koodi
println ("Nimi:" + nimi + ", osasto:" + osasto);
voitaisiin korvata lyhyemmällä mutta vastaavalla Kotlin-koodilla.
println ("Nimi: $ nimi, Osasto: $ dept")
Laajentaa ja toteuttaa
Java-ohjelmoijat tietävät, että luokka voi pidentää
toinen luokka ja toteuttaa
yksi tai useampi rajapinta. Kotlinissa näiden kahden samanlaisen käsitteen välillä ei ole syntaktista eroa; Kotlin käyttää kaksoispistettä molempiin. Esimerkiksi Java-koodi
julkinen luokka Opiskelija jatkuu Henkilökohtaiset välineet Vertailukelpoinen
kirjoitettaisiin yksinkertaisemmin Kotlinissa seuraavasti:
luokan opiskelija: Henkilö, vertailukelpoinen
Ei tarkistettuja poikkeuksia
Kotlin tukee poikkeuksia Java-kaltaisella tavalla yhdellä suurella erolla - Kotlinilla ei ole tarkistettuja poikkeuksia. Vaikka Java oli tarkoittanut hyviä aikomuksia, sitä on kritisoitu laajasti. Sinä voit silti heittää
ja saada kiinni
poikkeuksia, mutta Kotlin-kääntäjä ei pakota sinua tarttumaan mihinkään niistä.
Rakenneuudistus
Ajatella tuhoaminen yksinkertaisena tapana hajottaa esine sen osiksi. Tuhoava ilmoitus luo useita muuttujia kerralla. Alla olevassa luettelossa 3 on muutama esimerkki. Ensimmäisessä esimerkissä oletetaan, että muuttuja opiskelija-
on luokan esiintymä Opiskelija
, joka on määritelty alla olevassa luettelossa 12. Toinen esimerkki on otettu suoraan Kotlinin dokumentaatiosta.
Luettelo 3. Rakenneuudistusesimerkit
val (_, lName, fName) = opiskelija // poimi etu- ja sukunimi opiskelijaobjektista // alaviiva tarkoittaa, että emme tarvitse student.id for ((avain, arvo) kartalla) {// tee jotain avaimella ja arvo}
'jos' lausunnot ja ilmaisut
Kotlinissa jos
voidaan käyttää ohjausvirtaan kuten Java, mutta sitä voidaan käyttää myös lausekkeena. Java: n kryptainen kolminkertainen operaattori (?:
) korvataan selkeämmällä, mutta hieman pidemmällä jos
ilmaisu. Esimerkiksi Java-koodi
kaksinkertainen max = x> = y? x: y
kirjoitettaisiin Kotlinissa seuraavasti:
val max = if (x> = y), sitten x muu y
Kotlin on tässä tapauksessa hieman sanallisempi kuin Java, mutta syntaksit ovat kiistatta luettavampia.
'kun' korvaa kytkimen '
Pienin suosikkini ohjausrakenne C-tyyppisillä kielillä on vaihtaa
lausunto. Kotlin korvaa vaihtaa
lausunto a kun
lausunto. Listaus 4 on otettu suoraan Kotlinin dokumentaatiosta. Huomaa, että tauko
lauseita ei vaadita, ja voit helposti sisällyttää arvoalueita.
Listaus 4. "kun" -lauseke Kotlinissa
kun (x) {1: ssä - 10 -> tulosta ("x on alueella") voimassa olevilla numeroilla -> tulosta ("x on kelvollinen")! 10: ssä 20 -> tulosta ("x on alueen ulkopuolella ") else -> print (" mikään yllä olevista ")}
Yritä kirjoittaa Listaus 4 uudestaan perinteiseksi C / Javaksi vaihtaa
lausunnon, ja saat käsityksen siitä, kuinka paljon paremmin meillä on Kotlinin kanssa kun
lausunto. Myös samanlainen kuin jos
, kun
voidaan käyttää ilmaisuna. Tällöin tyydytetyn haaran arvosta tulee koko lausekkeen arvo.
Vaihda Java-lausekkeita
Java 12 esitteli kytkinlausekkeita. Samanlainen kuin Kotlin kun
, Java: n kytkinlausekkeet eivät vaadi tauko
lauseita, ja niitä voidaan käyttää lauseina tai ilmaisuina. Katso "Jakaaminen, vaihtaminen tai tauko? Lausekkeilla päättäminen ja iterointi" saadaksesi lisätietoja Java-lausekkeiden vaihtamisesta.
2. Yhden tyyppinen järjestelmä (melkein)
Java: lla on kaksi erillistä tyyppijärjestelmää, primitiiviset tyypit ja viitetyypit (eli objektit). On monia syitä, miksi Java sisältää kaksi erillistä järjestelmää. Itse asiassa se ei ole totta. Kuten artikkelissani on kuvattu, Primitiivien säilyttäminen Java: ssa, primitiivisille tyypeille on oikeastaan vain yksi syy - suorituskyky. Samoin kuin Scala, Kotlinilla on vain yksi tyyppijärjestelmä, koska Kotlinissa ei ole oleellisesti eroa primitiivisten tyyppien ja vertailutyyppien välillä. Kotlin käyttää primitiivisiä tyyppejä mahdollisuuksien mukaan, mutta käyttää esineitä tarvittaessa.
Joten miksi "melkein" varoitus? Koska Kotlinilla on myös erikoisluokkia edustamaan primitiivisten tyyppien taulukoita ilman autoboxing-yläpuolella: IntArray
, DoubleArray
, ja niin edelleen. JVM: llä DoubleArray
toteutetaan kaksinkertainen[]
. Onko käyttää DoubleArray
todella tehdä eroa? Katsotaan.
Vertailuarvo 1: Matriisikertaus
Tarkoittaessani Java-primitiivien tapaa esitin useita vertailutuloksia, joissa verrattiin Java-primitiivejä, Java-kääreen luokkia ja vastaavaa koodia muilla kielillä. Yksi vertailuarvoista oli yksinkertainen matriisikertaus. Kotlinin suorituskyvyn vertaamiseksi Java: iin loin Kotlinille kaksi matriisikertaistoteutusta, yhden käyttäen Taulukko
ja yksi käyttää Taulukko
. Luettelossa 5 näkyy Kotlin-toteutus käyttäen Taulukko
.
Listaus 5. Matriisin kertolasku Kotlinissa
hauska kertolasku (a: Array, b: Array): Array {if (! checkArgs (a, b)) heittää poikkeus ("Matriisit eivät ole yhteensopivia kertolaskuun") val nRows = a.koko val nCols = b [0]. size val result = Taulukko (nRows, {_ -> DoubleArray (nCols, {_ -> 0.0})}) (riviNum 0: sta nRows: iin) {for (colNum 0: sta nCols: iin) {var summa = 0,0 for (i 0: ssa, kunnes [0] .size) summa + = a [riviNum] [i] * b [i] [colNum] tulos [riviNum] [colNum] = summa}} palauttaa tuloksen}
Seuraavaksi vertasin kahden Kotlin-version suorituskykyä Java-versioon kaksinkertainen
ja Java kanssa Kaksinkertainen
, käynnissä kaikki neljä vertailuarvoa nykyisellä kannettavalla tietokoneellani. Koska jokaisen vertailuarvon suorittamisessa on vähän "melua", juoksin kaikki versiot kolme kertaa ja keskiarvoistin tuloksista, jotka on esitetty yhteenvetona taulukossa 1.
Taulukko 1. Matriisikertomuksen vertailuarvon ajonaikainen suorituskyky
Java ( | Java ( | Kotlin ( | Kotlin ( |
7.30 | 29.83 | 6.81 | 15.82 |
Olin hieman yllättynyt näistä tuloksista, ja piirrän kaksi otosta. Ensinnäkin Kotlinin suorituskyky DoubleArray
on selvästi parempi kuin Kotlinin suorituskyky Taulukko
, joka on selvästi parempi kuin Java, joka käyttää kääre-luokkaa Kaksinkertainen
. Toiseksi Kotlinin suorituskyky DoubleArray
on verrattavissa - ja tässä esimerkissä hieman paremmin - Java-suorituskykyyn primitiivistä tyyppiä käyttämällä kaksinkertainen
.
Kotlin on selvästikin tehnyt suuren työn optimoimalla erillistyyppisten järjestelmien tarpeen - lukuun ottamatta tarvetta käyttää luokkia, kuten DoubleArray
sijasta Taulukko
.
Vertailuarvo 2: SciMark 2.0
Alkuperäisartikkeliini sisälsi myös toisen, tieteellisemmän vertailuarvon, joka tunnetaan nimellä SciMark 2.0, joka on Java-vertailuarvo tieteelliselle ja numeeriselle laskennalle, jonka saa National Institute of Standards and Technology (NIST). SciMark-vertailuarvo mittaa useiden laskennallisten rutiinien suorituskykyä ja raportoi yhdistetyn pistemäärän likimääräisenä Mflops (miljoonia liukulukuoperaatioita sekunnissa). Siksi suuremmat luvut ovat parempia tälle vertailuarvolle.
IntelliJ IDEA: n avulla muutin SciMark-vertailuarvon Java-version Kotliniksi. IntelliJ IDEA muunnetaan automaattisesti kaksinkertainen[]
ja int []
Java-kielellä DoubleArray
ja IntArray
Kotlinissa. Sitten verrattiin primitiivien Java-versiota Kotlin-versioon DoubleArray
ja IntArray
. Kuten aikaisemmin, juoksin molemmat versiot kolme kertaa ja keskiarvoistin tuloksista, jotka on esitetty yhteenvetona taulukossa 2. Taulukossa esitetään jälleen suunnilleen vertailukelpoiset tulokset.
Taulukko 2. SciMark-vertailuarvon ajonaikainen suorituskyky
Java | Kotlin |
1818.22 | 1815.78 |