Programmēšana

Kāpēc Kotlins? Astoņas funkcijas, kas varētu pārliecināt Java izstrādātājus pāriet

Oficiāli izlaists 2016. gadā, Kotlin pēdējos gados ir piesaistījis lielu uzmanību, it īpaši tāpēc, ka Google paziņoja par savu atbalstu Kotlin kā alternatīvu Java Android platformās. Ar nesen paziņoto lēmumu padarīt Kotlin par vēlamo valodu Android, iespējams, jūs domājat, vai ir pienācis laiks sākt apgūt jaunu programmēšanas valodu. Ja tas tā ir, šis raksts varētu jums palīdzēt izlemt.

Kotlina atbrīvošanas vēsture

Kotlin tika paziņots 2011. gadā, taču pirmais stabilais izlaidums, versija 1.0, parādījās tikai 2016. gadā. Valoda ir bezmaksas un atvērta pirmkoda, kuru izstrādājusi JetBrains un kuras vadošais valodas dizainers ir Andrejs Breslavs. Kotlin 1.3.40 tika izlaists 2019. gada jūnijā.

Par Kotlinu

Kotlin ir moderna, statiski ierakstīta programmēšanas valoda, kurā ir gan objektorientētas, gan funkcionālas programmēšanas konstrukcijas. Tā mērķauditorija ir vairākas platformas, tostarp JVM, un tā ir pilnībā savietojama ar Java. Daudzos aspektos Kotlin varētu izskatīties Java, ja tā tiktu izstrādāta šodien. Šajā rakstā es iepazīstinu ar astoņām Kotlin funkcijām, kuras, manuprāt, Java izstrādātāji būs priecīgi atklāt.

  1. Tīra, kompakta sintakse
  2. Viena tipa sistēma (gandrīz)
  3. Nekāda drošība
  4. Funkcijas un funkcionālā programmēšana
  5. Datu klases
  6. Pagarinājumi
  7. Operatora pārslodze
  8. Augstākā līmeņa objekti un Singletona modelis

Sveika pasaule! Kotlins pret Java

1. saraksts parāda obligāto "Sveika, pasaule!" funkcija rakstīta Kotlīnā.

Saraksts 1. "Sveika, pasaule!" Kotlinā

 fun main () {println ("Sveika, pasaule!")} 

Cik vienkārši tas ir, šis piemērs atklāj galvenās atšķirības no Java.

  1. galvenais ir augstākā līmeņa funkcija; tas ir, Kotlina funkcijas nav jāievieto klases ietvaros.
  2. Nepastāv publisks statisks modifikatori. Kamēr Kotlinam ir redzamības modifikatori, noklusējums ir publiski un to var izlaist. Kotlins arī neatbalsta statisks modifikators, taču šajā gadījumā tas nav vajadzīgs, jo galvenais ir augstākā līmeņa funkcija.
  3. Kopš Kotlin 1.3 virknes masīva parametrs galvenais nav nepieciešama, un to var izlaist, ja to neizmanto. Ja nepieciešams, tas tiktu deklarēts kā args: Masīvs.
  4. Funkcijai nav norādīts atgriešanās veids. Kur Java izmanto spēkā neesošs, Kotlins izmanto Vienība, un, ja funkcijas atgriešanas tips ir Vienība, to var izlaist.
  5. Šajā funkcijā nav semikolu. Kotlīnā semikoli nav obligāti, un tāpēc līniju pārtraukumi ir nozīmīgi.

Tas ir pārskats, taču ir daudz vairāk uzzināt par to, kā Kotlins atšķiras no Java un daudzos gadījumos to uzlabo.

1. Tīrāka, kompaktāka sintakse

Java bieži tiek kritizēta par pārāk izteiksmīgu, taču daži izteiksmīgums var būt jūsu draugs, it īpaši, ja tas padara pirmkodu saprotamāku. Valodas dizaina izaicinājums ir samazināt daudzbalsību, vienlaikus saglabājot skaidrību, un es domāju, ka Kotlins ir tāls ceļš, lai tiktu galā ar šo izaicinājumu.

Kā redzējāt 1. sarakstā, Kotlin neprasa semikolus, un tas ļauj izlaist atgriešanās veidu Vienība funkcijas. Apsvērsim dažas citas funkcijas, kas palīdz padarīt Kotlin par tīrāku, kompaktāku alternatīvu Java.

Tipa secinājums

Kotlīnā jūs varat deklarēt mainīgo kā var x: Int = 5, vai arī jūs varat izmantot īsāku, bet tikpat skaidru versiju var x = 5. (Kaut arī Java tagad atbalsta var deklarācijas, šī funkcija parādījās tikai Java 10, ilgi pēc funkcijas parādīšanās Kotlinā.)

Kotlīnam arī ir val tikai lasāmu mainīgo deklarācijas, kas ir analogas Java mainīgajiem, kas deklarēti kā galīgais, kas nozīmē, ka mainīgo nevar mainīt. 2. saraksts sniedz piemēru.

2. saraksts. Tikai lasāmi mainīgie Kotlinā

 val x = 5 ... x = 6 // KĻŪDA: NESASTĀDĪS 

Rekvizīti pret laukiem

Kur Java ir lauki, Kotlin ir īpašības. Īpašības tiek deklarētas un tām piekļūst līdzīgi kā Java publiskajos laukos, taču Kotlins nodrošina piekļuves / mutatora funkciju noklusējuma ieviešanu īpašumiem; tas ir, Kotlins nodrošina gūt() funkcijas val īpašības un abas gūt() un komplekts () funkcijas var īpašības. Pielāgotas versijas gūt() un komplekts () vajadzības gadījumā var ieviest.

Lielākajai daļai Kotlinas īpašumu būs atbalsta lauki, taču ir iespējams definēt aprēķinātais īpašums, kas būtībā ir a gūt() funkcija bez atbalsta lauka. Piemēram, klasei, kas pārstāv personu, var būt īpašums dzimšanas datums un aprēķināts rekvizīts domēnam vecums.

Noklusējums pret nepārprotamu importu

Java netieši importē paketē definētās klases java.lang, bet visas pārējās klases ir skaidri jāimportē. Rezultātā daudzi Java avota faili sākas ar kolekcijas klašu importēšanu no java.util, I / O klases no plkst java.io, un tā tālāk. Pēc noklusējuma Kotlins netieši importē kotlins. *, kas ir aptuveni līdzīgs Java importēšanai java.lang. *, bet Kotlins arī importē kotlin.io. *, kotlin.collections. *, un nodarbības no vairākiem citiem iepakojumiem. Tāpēc Kotlina avota failiem parasti nepieciešams mazāk tiešu importu nekā Java avota failiem, īpaši klasēm, kurās tiek izmantotas kolekcijas un / vai standarta I / O.

Nav aicinājuma uz “jaunu” celtniekiem

Kotlinā atslēgvārds jauns nav nepieciešams, lai izveidotu jaunu objektu. Lai izsauktu konstruktoru, vienkārši izmantojiet klases nosaukumu ar iekavām. Java kods

 Students s = jauns students (...); // vai var s = jauns students (...); 

Kotlinā varētu rakstīt šādi:

 var s = students (...) 

Virknes veidnes

Stīgas var saturēt veidņu izteicieni, kas ir izteicieni, kas tiek vērtēti ar virknē ievietotiem rezultātiem. Veidnes izteiksme sākas ar dolāra zīmi ($) un sastāv vai nu no vienkārša nosaukuma, vai no patvaļīgas izteiksmes cirtainās iekavās. Virkņu veidnes var saīsināt virkņu izteiksmes, samazinot vajadzību pēc skaidras virkņu savienošanas. Piemēram, šāds Java kods

 println ("Vārds:" + vārds + ", departaments:" + departaments); 

varētu aizstāt ar īsāku, bet līdzvērtīgu Kotlina kodu.

 println ("Nosaukums: $ nosaukums, Departaments: $ dept") 

Paplašina un ievieš

Java programmētāji zina, ka klase var pagarināt cita klase un ieviest viena vai vairākas saskarnes. Kotlīnā starp abiem līdzīgajiem jēdzieniem nav sintaktiskas atšķirības; Kotlins abiem izmanto resnās zarnas. Piemēram, Java kods

 publiskā klase Skolēns pagarina Personas rīkus Salīdzināms 

Kotlinā būtu rakstīts vienkāršāk šādi:

 klases skolnieks: cilvēks, salīdzināms 

Nav pārbaudītu izņēmumu

Kotlins atbalsta izņēmumus tādā pašā veidā kā Java ar vienu lielu atšķirību - Kotlinam nav pārbaudītu izņēmumu. Lai gan tie bija labprātīgi, Java pārbaudītie izņēmumi ir plaši kritizēti. Jūs joprojām varat mest un noķert izņēmumi, taču Kotlin sastādītājs neliek jums noķert nevienu no tiem.

Pārstrukturēšana

Padomā par sagraujot kā vienkāršs veids, kā sadalīt objektu tā sastāvdaļās. Destrukturēšanas deklarācija vienlaikus rada vairākus mainīgos. Zemāk esošajā 3. sarakstā ir sniegti daži piemēri. Pirmajā piemērā pieņemsim šo mainīgo students ir klases gadījums Students, kas ir definēts turpmāk 12. sarakstā. Otrais piemērs ir ņemts tieši no Kotlin dokumentācijas.

Saraksts 3. Pārstrukturēšanas piemēri

 val (_, lName, fName) = students // izraksta vārdu un uzvārdu no studenta objekta // pasvītrojums nozīmē, ka mums nav nepieciešams student.id par ((atslēga, vērtība) kartē) {// kaut ko darīt ar atslēgu un vērtība} 

“ja” paziņojumi un izteicieni

Kotlīnā, ja var izmantot vadības plūsmai tāpat kā Java, bet to var izmantot arī kā izteiksmi. Java kriptiskais trīskāršais operators (?:) aizstāj ar skaidrāku, bet nedaudz garāku ja izteiksme. Piemēram, Java kods

 dubultā max = x> = y? x: y 

Kotlinā būtu rakstīts šādi:

val max = ja (x> = y), tad x cits y 

Kotlins šajā lietā ir nedaudz izteiksmīgāks par Java, taču sintakse neapšaubāmi ir lasāmāka.

"kad" aizstāj "slēdzi"

Mana vismazāk iecienītā vadības struktūra C veida valodās ir slēdzis paziņojums, apgalvojums. Kotlins aizstāj slēdzis paziņojums ar a kad paziņojums, apgalvojums. 4. saraksts tiek ņemts tieši no Kotlina dokumentācijas. Ievērojiet to pārtraukums paziņojumi nav nepieciešami, un jūs varat viegli iekļaut vērtību diapazonus.

Saraksts 4. “Kad” paziņojums Kotlīnā

 kad (x) {in 1..10 -> drukāt ("x ir diapazonā") ar validNumbers -> drukāt ("x ir derīgs")! 10..20 -> print ("x ir ārpus diapazona ") else -> print (" neviens no iepriekš minētajiem ")} 

Mēģiniet 4. ierakstu pārrakstīt kā tradicionālu C / Java slēdzis paziņojumu, un jūs uzzināsiet, cik daudz labāk mums ir ar Kotlina kad paziņojums, apgalvojums. Arī līdzīgi kā ja, kad var izmantot kā izteicienu. Tādā gadījumā apmierinātās filiāles vērtība kļūst par kopējās izteiksmes vērtību.

Pārslēdziet izteicienus Java valodā

Java 12 ieviesa slēdžu izteiksmes. Līdzīgi kā Kotlin kad, Java komutatora izteiksmēm nav nepieciešamas pārtraukums paziņojumus, un tos var izmantot kā izteikumus vai izteicienus. Skatiet sadaļu "Cilpa, pārslēgšana vai pārtraukums? Lēmumu pieņemšana un atkārtošana ar paziņojumiem", lai uzzinātu vairāk par komutācijas izteiksmēm Java.

2. Viena tipa sistēma (gandrīz)

Java ir divas atsevišķas tipa sistēmas, primitīvi tipi un atsauces tipi (vēl, objekti). Ir daudz iemeslu, kāpēc Java ietver divas atsevišķas tipa sistēmas. Patiesībā tā nav taisnība. Kā izklāstīts manā rakstā Primitive saglabāšanas Java gadījums, primitīviem veidiem patiesībā ir tikai viens iemesls - veiktspēja. Līdzīgi kā Scala, Kotlīnā ir tikai viena tipa sistēma, jo Kotlīnā būtībā nav atšķirības starp primitīviem un atsauces tipiem. Kotlins, ja iespējams, izmanto primitīvus veidus, bet vajadzības gadījumā izmantos objektus.

Tātad, kāpēc izteikt "gandrīz" atrunu? Tā kā Kotlīnam ir arī specializētas klases, kas pārstāv primitīvu veidu masīvus bez autoboxing virs galvas: IntArray, DoubleArray, un tā tālāk. JVM DoubleArray tiek īstenots kā dubultā []. Vai izmanto DoubleArray tiešām kaut ko mainīt? Paskatīsimies.

1. etalons: Matricas reizināšana

Izstrādājot Java primitīvu gadījumu, es parādīju vairākus etalona rezultātus, salīdzinot Java primitīvus, Java iesaiņošanas klases un līdzīgu kodu citās valodās. Viens no kritērijiem bija vienkārša matricas reizināšana. Lai salīdzinātu Kotlina veiktspēju ar Java, es izveidoju Kotlin divas matricas reizināšanas ieviešanas, vienu izmantojot Masīvs un vienu izmantojot Masīvs. 5. saraksts parāda Kotlin ieviešanu, izmantojot Masīvs.

Saraksts 5. Matricas reizināšana Kotlinā

 jautri reizināt (a: masīvs, b: masīvs): masīvs {if (! checkArgs (a, b)) mest Izņēmums ("Matricas nav saderīgas reizināšanai") val nRows = a.izmērs val nCols = b [0]. size val result = Masīvs (nRows, {_ -> DoubleArray (nCols, {_ -> 0.0})}) (rindaNum 0 līdz nRows) {for (colNum 0 līdz nCols) {var summa = 0,0 0, līdz [0] .size) summa + = a [rowNum] [i] * b [i] [colNum] rezultāts [rowNum] [colNum] = summa}} atgriežas rezultāts} 

Tālāk es salīdzināju divu Kotlin versiju veiktspēju ar Java ar dubultā un Java ar Dubultā, darbojas visi četri etaloni manā pašreizējā klēpjdatorā. Tā kā katra etalona izpildē ir neliels daudzums "trokšņa", es trīs reizes izpildīju visas versijas un vidēji aprēķināju rezultātus, kas apkopoti 1. tabulā.

1. tabula. Matricas reizināšanas etalona izpildlaika veiktspēja

Laika rezultāti (sekundēs)
Java

(dubultā)

Java

(Dubultā)

Kotlins

(DoubleArray)

Kotlins

(Masīvs)

7.3029.836.8115.82

Es biju nedaudz pārsteigts par šiem rezultātiem, un es izlozēju divus izņēmumus. Pirmkārt, Kotlina sniegums, izmantojot DoubleArray ir nepārprotami pārāka par Kotlin sniegumu, izmantojot Masīvs, kas ir acīmredzami pārāks par Java, izmantojot iesaiņošanas klasi Dubultā. Un, otrkārt, Kotlina sniegums, izmantojot DoubleArray ir salīdzināms - un šajā piemērā nedaudz labāks par - Java veiktspēju, izmantojot primitīvo tipu dubultā.

Nepārprotami Kotlins ir paveicis lielisku darbu, optimizējot nepieciešamību pēc atsevišķa tipa sistēmām - izņemot nepieciešamību izmantot tādas klases kā DoubleArray tā vietā Masīvs.

2. etalons: SciMark 2.0

Mans raksts par primitīviem ietvēra arī otru, zinātniskāku etalonu, kas pazīstams kā SciMark 2.0, kas ir Java standarts zinātniskai un skaitliskai skaitļošanai, kas pieejams Nacionālajā standartu un tehnoloģiju institūtā (NIST). SciMark etalons mēra vairāku skaitļošanas rutīnu veiktspēju un norāda kopējo punktu skaitu aptuvenā vērtībā Mflops (miljoniem peldošā komata operāciju sekundē). Tādējādi šim skaitlim ir labāki skaitļi.

Ar IntelliJ IDEA palīdzību es pārveidoju SciMark etalona Java versiju Kotlin. IntelliJ IDEA tiek automātiski pārveidota dubultā [] un int [] Java valodā DoubleArray un IntArray Kotlinā. Pēc tam es salīdzināju Java versiju, izmantojot primitīvus, ar Kotlin versiju, izmantojot DoubleArray un IntArray. Tāpat kā iepriekš, es abas versijas palaidu trīs reizes un vidēji aprēķināju rezultātus, kas apkopoti 2. tabulā. Atkal tabulā parādīti aptuveni salīdzināmi rezultāti.

2. tabula. SciMark etalona izpildlaika veiktspēja

Izrāde (Mflops)
JavaKotlins
1818.221815.78