Introduksjon til Kotlin-språket

1. Oversikt

I denne veiledningen skal vi ta en titt på Kotlin, et nytt språk i JVM-verdenen, og noen av dens grunnleggende funksjoner, inkludert klasser, arv, betingede uttalelser og looping-konstruksjoner.

Deretter vil vi se på noen av hovedfunksjonene som gjør Kotlin til et attraktivt språk, inkludert null sikkerhet, dataklasser, utvidelsesfunksjoner og String maler.

2. Maven-avhengigheter

For å bruke Kotlin i Maven-prosjektet ditt, må du legge til Kotlin-standardbiblioteket i pom.xml:

 org.jetbrains.kotlin kotlin-stdlib 1.0.4 

For å legge til JUnit-støtte for Kotlin, må du også inkludere følgende avhengigheter:

 org.jetbrains.kotlin kotlin-test-junit 1.0.4 test junit junit 4.12 test 

Du finner de nyeste versjonene av kotlin-stdlib, kotlin-test-junit og junit på Maven Central.

Til slutt må du konfigurere kildekatalogene og Kotlin-plugin for å kunne utføre en Maven-build:

 $ {project.basedir} / src / main / kotlin $ {project.basedir} / src / test / kotlin kotlin-maven-plugin org.jetbrains.kotlin 1.0.4 kompilere kompilere test-kompilere test-kompilere 

Du finner den nyeste versjonen av kotlin-maven-plugin i Maven Central.

3. Grunnleggende syntaks

La oss se på grunnleggende byggesteiner i Kotlin Language.

Det er noe likhet med Java (f.eks. Å definere pakker er på samme måte). La oss se på forskjeller.

3.1. Definere funksjoner

La oss definere en funksjon som har to Int-parametere med Int returtype:

morsom sum (a: Int, b: Int): Int {return a + b}

3.2. Definere lokale variabler

Tildel en gang (skrivebeskyttet) lokal variabel:

val a: Int = 1 val b = 1 val c: Int c = 1

Legg merke til den typen variabel b er utledet av en Kotlin-kompilator. Vi kunne også definere foranderlige variabler:

var x = 5 x + = 1

4. Valgfrie felt

Kotlin har grunnleggende syntaks for å definere et felt som kan være ugyldig (valgfritt). Når vi vil erklære at felttypen er null, må vi bruke typen som er forsynt med et spørsmålstegn:

val email: String?

Når du definerte nullbart felt, er det helt gyldig å tildele en null til det:

val email: String? = null

Det betyr at i et e-postfelt kan det være en null. Hvis vi vil skrive:

val email: String = "value"

Deretter må vi tilordne en verdi til e-postfeltet i samme uttalelse som vi erklærer e-post. Det kan ikke ha en nullverdi. Vi kommer tilbake til Kotlin null sikkerhet i et senere avsnitt.

5. Klasser

La oss demonstrere hvordan du lager en enkel klasse for å administrere en bestemt kategori av et produkt. Våre ItemManager klassen nedenfor har en standardkonstruktør som fyller ut to felt - categoryId og dbConnection - og et valgfritt e-post felt:

class ItemManager (val categoryId: String, val dbConnection: String) {var email = "" // ...}

At ItemManager (…) konstruere skaper konstruktør og to felt i klassen vår: categoryId og dbConnection

Merk at konstruktøren vår bruker val nøkkelord for argumentene - dette betyr at de tilsvarende feltene vil være endelig og uforanderlig. Hvis vi hadde brukt var nøkkelord (som vi gjorde da vi definerte e-post felt), så vil disse feltene være foranderlige.

La oss lage en forekomst av ItemManager ved hjelp av standardkonstruktøren:

ItemManager ("cat_id", "db: // connection")

Vi kunne konstruere ItemManager ved hjelp av navngitte parametere. Det er veldig nyttig når du har som i dette eksempelet funksjon som tar to parametere med samme type f.eks. String, og du vil ikke forveksle en ordre av dem. Ved å bruke navneparametere kan du eksplisitt skrive hvilken parameter som er tildelt. I klassen ItemManager det er to felt, categoryId og dbConnection slik at begge kan refereres til ved hjelp av navngitte parametere:

ItemManager (categoryId = "catId", dbConnection = "db: // Connection")

Det er veldig nyttig når vi trenger å overføre flere argumenter til en funksjon.

Hvis du trenger flere konstruktører, vil du definere dem ved hjelp av konstruktør nøkkelord. La oss definere en annen konstruktør som også setter e-post felt:

constructor (categoryId: String, dbConnection: String, email: String): this (categoryId, dbConnection) {this.email = email}

Merk at denne konstruktøren påkaller standardkonstruktøren som vi definerte ovenfor før du satte e-postfeltet. Og siden vi allerede definerte categoryId og dbConnection å være uforanderlig ved hjelp av val nøkkelord i standardkonstruktøren, trenger vi ikke å gjenta val nøkkelord i den ekstra konstruktøren.

La oss nå lage en forekomst ved hjelp av den ekstra konstruktøren:

ItemManager ("cat_id", "db: // connection", "[email protected]")

Hvis du vil definere en forekomstmetode på ItemManager, ville du gjort det ved hjelp av moro nøkkelord:

fun isFromSpecificCategory (catId: String): Boolean {return categoryId == catId}

6. Arv

Som standard er Kotlins klasser stengt for utvidelse - tilsvarer en klasse merket endelig i Java.

For å spesifisere at en klasse er åpen for utvidelse, vil du bruke åpen nøkkelord når du definerer klassen.

La oss definere en Punkt klasse som er åpen for utvidelse:

open class Item (val id: String, val name: String = "unknown_name") {open fun getIdOfItem (): String {return id}}

Merk at vi også betegnet getIdOfItem () metoden som åpen. Dette gjør at den kan overstyres.

La oss nå utvide Punkt klasse og overstyre getIdOfItem () metode:

class ItemWithCategory (id: String, name: String, val categoryId: String): Item (id, name) {override fun getIdOfItem (): String {return id + name}}

7. Betinget erklæring

I Kotlin, betinget uttalelse hvis tilsvarer en funksjon som returnerer en verdi. La oss se på et eksempel:

moro makeAnalyisOfCategory (catId: String): Enhet {val result = if (catId == "100") "Yes" else "No" println (result)}

I dette eksemplet ser vi at hvis catId er lik "100" betinget blokk returnerer "Ja" ellers returnerer den "Nei". Returnert verdi blir tildelt resultat.

Du kan lage en normal hvisellers blokkere:

val number = 2 if (number 10) {println ("tallet er større enn 10")}

Kotlin har også en veldig nyttig når kommando som fungerer som en avansert bryteruttalelse:

val name = "John" når (navn) {"John" -> println ("Hei mann") "Alice" -> println ("Hei dame")} 

8. Samlinger

Det finnes to typer samlinger i Kotlin: foranderlig og uforanderlig. Når vi lager en uforanderlig samling, betyr det at den er skrivebeskyttet:

val items = listOf (1, 2, 3, 4)

Det er ikke noe tilleggselement på denne listen.

Når vi ønsker å lage en foranderlig liste som kan endres, må vi bruke den mutableListOf () metode:

val rwList = mutableListOf (1, 2, 3) rwList.add (5)

En foranderlig liste har legge til() metode slik at vi kunne legge et element til den. Det finnes også tilsvarende metoder som andre typer samlinger: mutableMapOf (), mapOf (), setOf (), mutableSetOf ()

9. Unntak

Mekanismen for unntakshåndtering er veldig lik den i Java.

Alle unntaksklasser utvides Kastbar. Unntaket må ha en melding, stacktrace og en valgfri årsak. Hvert unntak i Kotlin er ukontrollert, noe som betyr at kompilatoren ikke tvinger oss til å fange dem.

For å kaste et unntaksobjekt, må vi bruke kasteuttrykket:

kast unntak ("msg")

Håndtering av unntak gjøres ved å bruke prøv ... fangstblokk (endelig valgfri):

prøv {} catch (e: SomeException) {} endelig {}

10. Lambdas

I Kotlin kunne vi definere lambdafunksjoner og overføre dem som argumenter til andre funksjoner.

La oss se hvordan vi definerer en enkel lambda:

val sumLambda = {a: Int, b: Int -> a + b}

Vi definerte sumLambda funksjon som tar to argumenter av typen Int som argument og kommer tilbake Int.

Vi kunne passere en lambda rundt:

@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. Looping Constructs

I Kotlin kan man gå gjennom samlinger ved å bruke en standard for i konstruere:

val tall = arrayOf ("første", "andre", "tredje", "fjerde")
for (n i tall) {println (n)}

Hvis vi vil iterere over en rekke heltall, kan vi bruke en områdekonstruksjon:

for (i i 2..9 trinn 2) {println (i)}

Vær oppmerksom på at rekkevidden i eksemplet ovenfor inkluderer begge sider. De steg parameteren er valgfri, og det tilsvarer å øke telleren to ganger i hver iterasjon. Utgangen vil være følgende:

2 4 6 8

Vi kan bruke en rekkevidde til () funksjon som er definert på Int klasse på følgende måte:

1.rangeTo (10) .kart {it * 2}

Resultatet vil inneholde (merk at rekkevidde til () er også inkludert):

[2, 4, 6, 8, 10, 12, 14, 16, 18, 20]

12. Null Safety

La oss se på en av hovedtrekkene i Kotlin - null sikkerhet, som er innebygd i språket. For å illustrere hvorfor dette er nyttig, vil vi lage enkle tjenester som returnerer en Punkt gjenstand:

class ItemService {fun findItemNameForId (id: String): Item? {val itemId = UUID.randomUUID (). toString () return Item (itemId, "name- $ itemId"); }}

Det viktige å legge merke til er returnert type av denne metoden. Det er et objekt etterfulgt av spørsmålstegnet. Det er en konstruksjon fra Kotlin-språket, noe som betyr det Punkt returnert fra den metoden kan være null. Vi må håndtere saken på kompileringstidspunktet og bestemme hva vi vil gjøre med det objektet (det tilsvarer mer eller mindre Java 8 Valgfri type).

Hvis metodesignaturen har type uten spørsmålstegn:

fun findItemNameForId (id: String): Element

da trenger ikke ringekode å håndtere et nullsak fordi det er garantert av kompilatoren og Kotlin-språket, at det returnerte objektet ikke kan være null.

Ellers, hvis det er et nullbart objekt sendt til en metode, og saken ikke blir behandlet, vil den ikke kompilere.

La oss skrive en testsak for Kotlin-type sikkerhet:

val id = "item_id" val itemService = ItemService () val result = itemService.findItemNameForId (id) assertNotNull (result? .let {it -> it.id}) assertNotNull (result !!. id) 

Vi ser her at etter kjøring av metoden findItemNameForId (), den returnerte typen er av Kotlin Nullable. For å få tilgang til et felt av det objektet (id), må vi behandle saken på kompileringstidspunktet. Metode la() vil bare kjøres hvis et resultat ikke er null. Jegd feltet kan nås inne i en lambda-funksjon fordi det er null trygt.

En annen måte å få tilgang til det nullbare objektfeltet er å bruke Kotlin-operatøren !!. Det tilsvarer:

hvis (resultat == null) {throwNpe (); } returnere resultat;

Kotlin vil sjekke om objektet er et null i så fall vil det kaste a NullPointerException, ellers vil den returnere en skikkelig gjenstand. Funksjon throwNpe () er en intern Kotlin-funksjon.

13. Dataklasser

En veldig fin språkkonstruksjon som kan bli funnet i Kotlin er dataklasser (det tilsvarer "case class" fra Scala-språk). Hensikten med slike klasser er å bare holde data. I vårt eksempel hadde vi en Punkt klasse som bare inneholder dataene:

dataklasse Element (val id: String, val name: String)

Kompilatoren vil lage metoder for oss hashCode (), er lik(), og toString (). Det er god praksis å gjøre dataklasser uforanderlige ved å bruke a val nøkkelord. Dataklasser kan ha standard feltverdier:

dataklasse Element (val id: String, val name: String = "unknown_name")

Vi ser det Navn feltet har en standardverdi “ukjent_navn”.

14. Utvidelsesfunksjoner

Anta at vi har en klasse som er en del av tredjepartsbiblioteket, men vi vil utvide den med en ekstra metode. Kotlin tillater oss å gjøre dette ved å bruke utvidelsesfunksjoner.

La oss se på et eksempel der vi har en liste over elementer, og vi vil ta et tilfeldig element fra den listen. Vi ønsker å legge til en ny funksjon tilfeldig() til tredje part Liste klasse.

Slik ser det ut i Kotlin:

morsom List.random (): T? {if (this.isEmpty ()) return null return get (ThreadLocalRandom.current (). nextInt (count ()))}

Det viktigste å legge merke til her er en signatur av metoden. Metoden er foran et navn på klassen som vi legger til denne ekstra metoden til.

Inne i utvidelsesmetoden opererer vi på et omfang av en liste, og bruker derfor dette ga bruk tilgang til listen forekomst metoder som er tom() eller telle(). Da klarer vi å ringe tilfeldig() metode på en liste som er innenfor det omfanget:

morsom getRandomElementOfList (liste: Liste): T? {return list.random ()}

Vi opprettet en metode som tar en liste og deretter kjører tilpasset utvidelsesfunksjon tilfeldig() som tidligere var definert. La oss skrive en test case for vår nye funksjon:

valelementer = listOf ("a", "b", "c") valresultat = ListExtension (). getRandomElementOfList (elementer) assertTrue (elements.contains (resultat)) 

Muligheten for å definere funksjoner som "utvider" tredjepartsklasser er en veldig kraftig funksjon og kan gjøre koden vår mer kortfattet og lesbar.

15. Strengmaler

En veldig fin funksjon av Kotlin-språket er en mulighet til å bruke maler til Strings. Det er veldig nyttig fordi vi ikke trenger å sammenkoble Strings manuelt:

val firstName = "Tom" val secondName = "Mary" val concatOfNames = "$ firstName + $ secondName" val sum = "four: $ {2 + 2}" 

Vi kan også evaluere et uttrykk inne i ${} blokkere:

val itemManager = ItemManager ("cat_id", "db: // connection") val result = "funksjonsresultat: $ {itemManager.isFromSpecificCategory (" 1 ")}"

16. Kotlin / Java-interoperabilitet

Kotlin - Java-interoperabilitet er sømløst enkelt. La oss anta at vi har en Java-klasse med en metode som fungerer Streng:

class StringUtils {public static String toUpperCase (String name) {return name.toUpperCase (); }}

Nå vil vi utføre den koden fra Kotlin-klassen vår. Vi trenger bare å importere den klassen, og vi kan kjøre Java-metoden fra Kotlin uten problemer:

val name = "tom" val res = StringUtils.toUpperCase (name) assertEquals (res, "TOM")

Som vi ser, brukte vi java-metoden fra Kotlin-koden.

Å ringe Kotlin-kode fra en Java er også veldig enkelt. La oss definere enkel Kotlin-funksjon:

klasse MathematicsOperations {fun addTwoNumbers (a: Int, b: Int): Int {return a + b}}

Utfører addTwoNumbers () fra Java-kode er veldig enkelt:

int res = new MathematicsOperations (). addTwoNumbers (2, 4); assertEquals (6, res);

Vi ser at samtalen til Kotlin-koden var gjennomsiktig for oss.

Når vi definerer en metode i java, er returtypen a tomrom, i Kotlin vil returnert verdi være av Enhet type.

Det er noen spesielle identifikatorer på Java-språk ( er, gjenstand, i, ..) at når de brukes i Kotlin-kode, må du unnslippe. For eksempel kan vi definere en metode som har et navn gjenstand() men vi må huske å unnslippe det navnet, da dette er en spesiell identifikator i java:

morsom `objekt` (): Streng {return" dette er objekt "}

Så kunne vi utføre den metoden:

`objekt` ()

17. Konklusjon

Denne artikkelen introduserer Kotlin-språket, og det er viktige funksjoner. Det starter med å introdusere enkle begreper som sløyfer, betingede uttalelser og definere klasser. Viser så noen mer avanserte funksjoner som utvidelsesfunksjoner og null sikkerhet.

Implementeringen av alle disse eksemplene og kodebiter finner du i GitHub-prosjektet.


$config[zx-auto] not found$config[zx-overlay] not found