Zece funcții Kotlin pentru a stimula dezvoltarea Android

Publicat: 2022-03-11

Introducere

Cu ceva timp în urmă, Tomasz a introdus dezvoltarea Kotlin pe Android. Pentru a vă aminti: Kotlin este un nou limbaj de programare dezvoltat de Jetbrains, compania din spatele unuia dintre cele mai populare IDE-uri Java, IntelliJ IDEA. La fel ca Java, Kotlin este un limbaj de uz general. Deoarece respectă codul de octet al mașinii virtuale Java (JVM), poate fi folosit alături de Java și nu vine cu o suprasarcină de performanță.

În acest articol, voi acoperi primele 10 funcții utile pentru a vă stimula dezvoltarea Android.

Notă : la momentul scrierii acestui articol, versiunile reale erau Android Studio 2.1.1. și Kotlin 1.0.2.

Kotlin

V-ați săturat de codul Java fără sfârșit? Încearcă Kotlin și economisește-ți timp și sănătate.
Tweet

Configurare Kotlin

Deoarece Kotlin este dezvoltat de JetBrains, este bine acceptat atât în ​​Android Studio, cât și în IntelliJ.

Primul pas este să instalați pluginul Kotlin. După ce ați făcut acest lucru cu succes, noi acțiuni vor fi disponibile pentru conversia Java în Kotlin. Două opțiuni noi sunt:

  1. Creați un nou proiect Android și configurați Kotlin în proiect.
  2. Adăugați suport Kotlin la un proiect Android existent.

Pentru a afla cum să creați un nou proiect Android, consultați ghidul oficial pas cu pas. Pentru a adăuga suport Kotlin la un proiect nou creat sau existent, deschideți caseta de dialog pentru acțiunea de căutare folosind Command + Shift + A pe Mac sau Ctrl + Shift + A pe Windows/Linux și invocați acțiunea Configure Kotlin in Project .

Pentru a crea o nouă clasă Kotlin, selectați:

  • File > New > Kotlin file/class sau
  • File > New > Kotlin activity

Alternativ, puteți crea o clasă Java și o puteți converti în Kotlin folosind acțiunea menționată mai sus. Amintiți-vă, îl puteți folosi pentru a converti orice clasă, interfață, enumerare sau adnotare, iar aceasta poate fi folosită pentru a compara cu ușurință Java cu codul Kotlin.

Un alt element util care economisește multă tastare sunt extensiile Kotlin. Pentru a le folosi, trebuie să aplicați un alt plugin în fișierul modul build.gradle :

 apply plugin: 'kotlin-android-extensions'

Avertisment : dacă utilizați acțiunea plugin-ului Kotlin pentru a vă configura proiectul, acesta va pune următorul cod în fișierul build.gradle de nivel superior:

 buildscript { ext.kotlin_version = '1.0.2' repositories { jcenter() } dependencies { classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" // NOTE: Do not place your application dependencies here; they belong // in the individual module build.gradle files } }

Acest lucru va face ca extensia să nu funcționeze. Pentru a remedia acest lucru, pur și simplu copiați acel cod în fiecare dintre modulele de proiect în care doriți să utilizați Kotlin.

Dacă configurați totul corect, ar trebui să puteți rula și testa aplicația în același mod în care ați face-o într-un proiect standard Android, dar acum folosind Kotlin.

Economisiți timp cu Kotlin

Deci, să începem cu descrierea unor aspecte cheie ale limbajului Kotlin și prin a oferi sfaturi despre cum puteți economisi timp folosindu-l în loc de Java.

Caracteristica #1: Import static layout

Unul dintre cele mai comune coduri standard din Android este utilizarea funcției findViewById() pentru a obține referințe la vederile dvs. în Activități sau Fragmente.

Există soluții, cum ar fi biblioteca Butterknife, care salvează ceva tastare, dar Kotlin face un alt pas, permițându-vă să importați toate referințele la vizualizări din aspect cu un singur import.

De exemplu, luați în considerare următorul aspect XML al activității:

 <?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:andro xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:paddingBottom="@dimen/activity_vertical_margin" android:paddingLeft="@dimen/activity_horizontal_margin" android:paddingRight="@dimen/activity_horizontal_margin" android:paddingTop="@dimen/activity_vertical_margin" tools:context="co.ikust.kotlintest.MainActivity"> <TextView android: android:layout_width="wrap_content" android:layout_height="wrap_content"/> </RelativeLayout>

Și codul de activitate însoțitor:

 package co.ikust.kotlintest import android.support.v7.app.AppCompatActivity import android.os.Bundle import kotlinx.android.synthetic.main.activity_main.* class MainActivity : AppCompatActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) helloWorldTextView.text = "Hello World!" } }

Pentru a obține referințele pentru toate vizualizările din aspect cu un ID definit, utilizați extensia Android Kotlin Anko. Nu uitați să introduceți această declarație de import:

 import kotlinx.android.synthetic.main.activity_main.*

Rețineți că nu trebuie să scrieți punct și virgulă la sfârșitul liniilor în Kotlin, deoarece sunt opționale.

TextView din aspect este importat ca o instanță TextView cu numele egal cu ID-ul vizualizării. Nu vă lăsați confuzi de sintaxa, care este folosită pentru a seta eticheta:

 helloWorldTextView.text = "Hello World!"

Vom acoperi asta în scurt timp.

Avertismente :

  • Asigurați-vă că importați aspectul corect, altfel referințele de vizualizare importate vor avea o valoare null .
  • Când utilizați fragmente, asigurați-vă că referințele View importate sunt utilizate după apelul funcției onCreateView() . Importați aspectul în funcția onCreateView() și utilizați referințele View pentru a configura interfața de utilizare în onViewCreated() . Referințele nu vor fi alocate înainte ca metoda onCreateView() să se termine.

Caracteristica #2: Scrierea cursurilor POJO cu Kotlin

Ceva care va economisi cel mai mult timp cu Kotlin este scrierea claselor POJO (Plain Old Java Object) folosite pentru a deține date. De exemplu, în corpul cererii și răspunsului unui API RESTful. În aplicațiile care se bazează pe API-ul RESTful, vor exista multe clase de acest fel.

În Kotlin, se fac multe pentru tine, iar sintaxa este concisă. De exemplu, luați în considerare următoarea clasă în Java:

 public class User { private String firstName; private String lastName; public String getFirstName() { return firstName; } public void setFirstName(String firstName) { this.firstName = firstName; } public String getLastName() { return lastName; } public void setLastName(String lastName) { this.lastName = lastName; } }

Când lucrați cu Kotlin, nu trebuie să scrieți din nou cuvântul cheie public. În mod implicit, totul este de interes public. De exemplu, dacă doriți să declarați o clasă, scrieți pur și simplu:

 class MyClass { }

Echivalentul codului Java de mai sus în Kotlin:

 class User { var firstName: String? = null var lastName: String? = null }

Ei bine, asta economisește multă tastare, nu-i așa? Să trecem prin codul Kotlin.

Kotlin economisește multă tastare

Când definiți variabile în Kotlin, există două opțiuni:

  • Variabile mutabile, definite de cuvântul cheie var .
  • Variabile imuabile, definite de cuvântul cheie val .

Următorul lucru de remarcat este că sintaxa diferă puțin de Java; mai întâi, declarați numele variabilei și apoi urmați cu type. De asemenea, în mod implicit, proprietățile sunt tipuri non-null, ceea ce înseamnă că nu pot accepta valoare null . Pentru a defini o variabilă pentru a accepta o valoare null , trebuie adăugat un semn de întrebare după tip. Vom vorbi despre asta și despre siguranța nulă în Kotlin mai târziu.

Un alt lucru important de remarcat este că Kotlin nu are capacitatea de a declara câmpuri pentru clasă; numai proprietățile pot fi definite. Deci, în acest caz, firstName și lastName sunt proprietăți cărora li s-au atribuit metode implicite getter/setter. După cum am menționat, în Kotlin, ambele sunt publice în mod implicit.

Accesorii personalizați pot fi scrisi, de exemplu:

 class User { var firstName: String? = null var lastName: String? = null val fullName: String? get() firstName + " " + lastName }

Din exterior, când vine vorba de sintaxă, proprietățile se comportă ca câmpuri publice în Java:

 val userName = user.firstName user.firstName = "John"

Rețineți că noua proprietate fullName este numai pentru citire (definită de cuvântul cheie val ) și are un getter personalizat; pur și simplu adaugă numele și prenumele.

Toate proprietățile din Kotlin trebuie să fie atribuite atunci când sunt declarate sau sunt într-un constructor. Există unele cazuri când acest lucru nu este convenabil; de exemplu, pentru proprietăți care vor fi inițializate prin injecția de dependență. În acest caz, poate fi folosit un modificator lateinit . Iată un exemplu:

 class MyClass { lateinit var firstName : String; fun inject() { firstName = "John"; } }

Mai multe detalii despre proprietăți pot fi găsite în documentația oficială.

Caracteristica #3: Moștenirea clasei și constructorii

Kotlin are o sintaxă mai concisă și atunci când vine vorba de constructori.

Constructorii

Clasele Kotlin au un constructor primar și unul sau mai mulți constructori secundari. Un exemplu de definire a unui constructor primar:

 class User constructor(firstName: String, lastName: String) { }

Constructorul primar merge după numele clasei în definiția clasei. Dacă constructorul principal nu are adnotări sau modificatori de vizibilitate, cuvântul cheie constructor poate fi omis:

 class Person(firstName: String) { }

Rețineți că un constructor primar nu poate avea niciun cod; orice inițializare trebuie făcută în blocul de cod init :

 class Person(firstName: String) { init { //perform primary constructor initialization here } }

Mai mult, un constructor primar poate fi folosit pentru a defini și inițializa proprietăți:

 class User(var firstName: String, var lastName: String) { // ... }

La fel ca și cele obișnuite, proprietățile definite dintr-un constructor primar pot fi imuabile ( val ) sau mutabile ( var ).

Clasele pot avea și constructori secundari; sintaxa pentru definirea unuia este următoarea:

 class User(var firstName: String, var lastName) { constructor(name: String, parent: Person) : this(name) { parent.children.add(this) } }

Rețineți că fiecare constructor secundar trebuie să delege unui constructor primar. Acest lucru este similar cu Java, care utilizează this cuvânt cheie:

 class User(val firstName: String, val lastName: String) { constructor(firstName: String) : this(firstName, "") { //... } }

Când instanțiați clase, rețineți că Kotlin nu are cuvinte cheie new , la fel ca Java. Pentru a instanția clasa de User menționată mai sus, utilizați:

 val user = User("John", "Doe)

Prezentarea Moștenirii

În Kotlin, toate clasele se extind de la Any , care este similar cu Object în Java. În mod implicit, clasele sunt închise, ca și clasele finale în Java. Deci, pentru a extinde o clasă, aceasta trebuie să fie declarată ca open sau abstract :

 open class User(val firstName, val lastName) class Administrator(val firstName, val lastName) : User(firstName, lastName)

Rețineți că trebuie să delegați la constructorul implicit al clasei extinse, care este similar cu apelarea metodei super() în constructorul unei clase noi în Java.

Pentru mai multe detalii despre cursuri, verificați documentația oficială.

Caracteristica #4: Expresii Lambda

Expresiile Lambda, introduse cu Java 8, sunt una dintre caracteristicile sale preferate. Cu toate acestea, lucrurile nu sunt atât de strălucitoare pe Android, deoarece încă acceptă doar Java 7 și se pare că Java 8 nu va fi acceptat în curând. Așadar, soluțiile, cum ar fi Retrolambda, aduc expresii lambda pe Android.

Cu Kotlin, nu sunt necesare biblioteci sau soluții suplimentare.

Funcții în Kotlin

Să începem prin a trece rapid peste sintaxa funcției din Kotlin:

 fun add(x: Int, y: Int) : Int { return x + y }

Valoarea returnată a funcției poate fi omisă și, în acest caz, funcția va returna Int . Merită să repetăm ​​că totul în Kotlin este un obiect, extins de la Any și nu există tipuri primitive.

Un argument al funcției poate avea o valoare implicită, de exemplu:

 fun add(x: Int, y: Int = 1) : Int { return x + y; }

În acest caz, funcția add() poate fi invocată trecând doar argumentul x . Codul Java echivalent ar fi:

 int add(int x) { Return add(x, 1); } int add(int x, int y) { return x + y; }

Un alt lucru frumos atunci când se apelează o funcție este că pot fi folosite argumente numite. De exemplu:

 add(y = 12, x = 5)

Pentru mai multe detalii despre funcții, consultați documentația oficială.

Utilizarea expresiilor Lambda în Kotlin

Expresiile Lambda din Kotlin pot fi văzute ca funcții anonime în Java, dar cu o sintaxă mai concisă. De exemplu, să arătăm cum să implementăm ascultătorul de clic în Java și Kotlin.

În Java:

 view.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { Toast.makeText(v.getContext(), "Clicked on view", Toast.LENGTH_SHORT).show(); } };

În Kotlin:

 view.setOnClickListener({ view -> toast("Click") })

Wow! Doar o linie de cod! Putem vedea că expresia lambda este înconjurată de bretele. Parametrii sunt declarați mai întâi, iar corpul merge după semnul -> . Cu ascultătorul de clic, tipul pentru parametrul de vizualizare nu este specificat, deoarece poate fi dedus. Corpul este pur și simplu un apel la funcția toast() pentru afișarea toast, pe care o oferă Kotlin.

De asemenea, dacă parametrii nu sunt utilizați, îi putem omite:

 view.setOnClickListener({ toast("Click") })

Kotlin are biblioteci Java optimizate, iar orice funcție care primește o interfață cu o singură metodă pentru un argument poate fi apelată cu un argument de funcție (în loc de Interfață).

În plus, dacă funcția este ultimul parametru, aceasta poate fi mutată din paranteză:

 view.setOnClickListener() { toast("Click") }

În cele din urmă, dacă funcția are un singur parametru care este o funcție, parantezele pot fi omise:

 view.setOnClickListener { toast("Click") }

Pentru mai multe informații, consultați cartea Kotlin pentru dezvoltatori Android de Antonio Leiva și documentația oficială.

Funcții de extensie

Kotlin, similar cu C#, oferă posibilitatea de a extinde clasele existente cu funcționalități noi prin utilizarea funcțiilor de extensie. De exemplu, o metodă de extensie care ar calcula hash-ul MD5 al unui String :

 fun String.md5(): ByteArray { val digester = MessageDigest.getInstance("MD5") digester.update(this.toByteArray(Charset.defaultCharset())) return digester.digest() }

Rețineți că numele funcției este precedat de numele clasei extinse (în acest caz, String ) și că instanța clasei extinse este disponibilă prin intermediul this cuvânt cheie.

Funcțiile de extensie sunt echivalente cu funcțiile utilitare Java. Exemplul de funcție în Java ar arăta astfel:

 public static int toNumber(String instance) { return Integer.valueOf(instance); }

Exemplul de funcție trebuie plasat într-o clasă Utility. Aceasta înseamnă că funcțiile de extensie nu modifică clasa extinsă originală, ci sunt o modalitate convenabilă de a scrie metode utilitare.

Caracteristica #5: Siguranță nulă

Unul dintre lucrurile pe care le deranjezi cel mai mult în Java este probabil NullPointerException . Null-safety este o caracteristică care a fost integrată în limbajul Kotlin și este atât de implicită încât, de obicei, nu va trebui să vă faceți griji. Documentația oficială afirmă că singurele cauze posibile ale NullPointerExceptions sunt:

  • Un apel explicit pentru a arunca NullPointerException .
  • Folosind !! operator (pe care îl voi explica mai târziu).
  • Cod Java extern.
  • Dacă proprietatea lateinit este accesată în constructor înainte de a fi inițializată, va fi lansată o excepție UninitializedPropertyAccessException .

În mod implicit, toate variabilele și proprietățile din Kotlin sunt considerate non-null (nu pot păstra o valoare null ) dacă nu sunt declarate în mod explicit ca nule. După cum sa menționat deja, pentru a defini o variabilă care să accepte o valoare null , trebuie adăugat un semn de întrebare după tip. De exemplu:

 val number: Int? = null

Cu toate acestea, rețineți că următorul cod nu se va compila:

 val number: Int? = null number.toString()

Acest lucru se datorează faptului că compilatorul efectuează verificări null . Pentru compilare, trebuie adăugată o verificare null :

 val number: Int? = null if(number != null) { number.toString(); }

Acest cod se va compila cu succes. Ce face Kotlin în fundal, în acest caz, este că number devine nun-null ( Int în loc de Int? ) în interiorul blocului if.

Verificarea null poate fi simplificată folosind operatorul de apel sigur ( ?. ):

 val number: Int? = null number?.toString()

A doua linie va fi executată numai dacă numărul nu este null . Puteți folosi chiar și celebrul operator Elvis ( ?: ):

 val number Int? = null val stringNumber = number?.toString() ?: "Number is null"

Dacă expresia din stânga lui ?: nu este null , este evaluată și returnată. În caz contrar, rezultatul expresiei din dreapta este returnat. Un alt lucru frumos este că puteți folosi throw sau return în partea dreaptă a operatorului Elvis, deoarece sunt expresii în Kotlin. De exemplu:

 fun sendMailToUser(user: User) { val email = user?.email ?: throw new IllegalArgumentException("User email is null") //... }

Cel!! Operator

Dacă doriți ca o NullPointerException să fie lansată în același mod ca în Java, puteți face asta cu !! operator. Următorul cod va lansa o NullPointerException :

 val number: Int? = null number!!.toString()

Casting

Castificarea s-a încheiat folosind un cuvânt cheie as :

 val x: String = y as String

Această distribuție este considerată „Nesigură”, deoarece va arunca ClassCastException dacă nu este posibilă distribuția, așa cum face Java. Există un operator de distribuție „Safe” care returnează valoarea null în loc să arunce o excepție:

 val x: String = y as? String

Pentru mai multe detalii despre turnare, verificați secțiunea Type Casts and Casts din documentația oficială, iar pentru mai multe detalii despre siguranța null , verificați secțiunea Null-Safety.

proprietăți lateinit

Există un caz în care utilizarea proprietăților lateinit poate provoca o excepție similară cu NullPointerException . Luați în considerare următoarea clasă:

 class InitTest { lateinit var s: String; init { val len = this.s.length } }

Acest cod se va compila fără avertisment. Cu toate acestea, de îndată ce este creată o instanță de TestClass , va fi lansată o excepție UninitializedPropertyAccessException deoarece proprietatea s este accesată înainte de a fi inițializată.

Caracteristica #6: Funcționează with()

Funcția with() este utilă și vine cu biblioteca standard Kotlin. Poate fi folosit pentru a salva unele tastări dacă trebuie să accesați multe proprietăți ale unui obiect. De exemplu:

 with(helloWorldTextView) { text = "Hello World!" visibility = View.VISIBLE }

Primește un obiect și o funcție de extensie ca parametri. Blocul de cod (în acolade) este o expresie lambda pentru funcția de extensie a obiectului specificat ca prim parametru.

Caracteristica #7: Supraîncărcarea operatorului

Cu Kotlin, implementările personalizate pot fi furnizate pentru un set predefinit de operatori. Pentru a implementa un operator, trebuie furnizată o funcție de membru sau o funcție de extensie cu numele dat.

De exemplu, pentru a implementa operatorul de multiplicare, trebuie furnizată o funcție membru sau o funcție de extensie, cu numele times(argument) :

 operator fun String.times(b: Int): String { val buffer = StringBuffer() for (i in 1..b) { buffer.append(this) } return buffer.toString() }

Exemplul de mai sus arată o implementare a operatorului binar * pe String . De exemplu, următoarea expresie va atribui valoarea „TestTestTestTest” unei variabile newString :

 val newString = "Test" * 4

Deoarece funcțiile de extensie pot fi utilizate, înseamnă că comportamentul implicit al operatorilor pentru toate obiectele poate fi modificat. Aceasta este o sabie cu două tăișuri și trebuie folosită cu prudență. Pentru o listă de nume de funcții pentru toți operatorii care pot fi supraîncărcați, consultați documentația oficială.

O altă mare diferență față de Java sunt operatorii == și != . Operator == se traduce prin:

 a?.equals(b) ?: b === null

În timp ce operatorul != se traduce prin:

 !(a?.equals(b) ?:

Ceea ce înseamnă asta, este că folosirea == nu face o verificare a identității ca în Java (comparați dacă instanțele unui obiect sunt aceleași), ci se comportă la fel ca metoda equals() împreună cu verificările null .

Pentru a efectua verificarea identității, operatorii === și !== trebuie utilizați în Kotlin.

Caracteristica #8: Proprietăți delegate

Anumite proprietăți au anumite comportamente comune. De exemplu:

  • Proprietăți inițiale lazy care sunt inițializate la primul acces.
  • Proprietăți care implementează Observable în modelul Observer.
  • Proprietăți care sunt stocate într-o hartă, în schimb, ca câmpuri separate.

Pentru ca astfel de cazuri să fie mai ușor de implementat, Kotlin acceptă Proprietăți delegate :

 class SomeClass { var p: String by Delegate() }

Aceasta înseamnă că funcțiile getter și setter pentru proprietatea p sunt gestionate de o instanță a unei alte clase, Delegate .

Un exemplu de delegat pentru proprietatea String :

 class Delegate { operator fun getValue(thisRef: Any?, property: KProperty<*>): String { return "$thisRef, thank you for delegating '${property.name}' to me!" } operator fun setValue(thisRef: Any?, property: KProperty<*>, value: String) { println("$value has been assigned to '${property.name} in $thisRef.'") } }

Exemplul de mai sus afișează un mesaj când o proprietate este atribuită sau citită.

Delegații pot fi creați atât pentru proprietățile mutabile ( var ) cât și pentru numai citire ( val ).

Pentru o proprietate numai în citire, metoda getValue trebuie implementată. Este nevoie de doi parametri (luați din documentația oficială):

  • receptor - trebuie să fie același sau un supertip al proprietarului proprietății (pentru proprietățile de extensie, este tipul care se extinde).
  • metadate - trebuie să fie de tipul KProperty<*> sau supertipul acesteia.

Această funcție trebuie să returneze același tip ca proprietatea sau subtipul acesteia.

Pentru o proprietate mutabilă, un delegat trebuie să furnizeze suplimentar o funcție numită setValue care ia următorii parametri:

  • receptor - la fel ca pentru getValue() .
  • metadate - la fel ca pentru getValue() .
  • valoare nouă - trebuie să fie de același tip cu o proprietate sau cu supertipul acesteia.

Există câțiva delegați standard care vin cu Kotlin care acoperă cele mai comune situații:

  • Leneş
  • Observabil
  • Vetoabil

Leneş

Lazy este un delegat standard care ia ca parametru o expresie lambda. Expresia lambda transmisă este executată prima dată când metoda getValue() este apelată.

În mod implicit, evaluarea proprietăților leneșe este sincronizată. Dacă nu sunteți preocupat de multi-threading, puteți utiliza lazy(LazyThreadSafetyMode.NONE) { … } pentru a obține performanță suplimentară.

Observabil

Delegates.observable() este pentru proprietăți care ar trebui să se comporte ca Observabile în modelul Observer. Acceptă doi parametri, valoarea inițială și o funcție care are trei argumente (proprietate, valoare veche și valoare nouă).

Expresia lambda dată va fi executată de fiecare dată când metoda setValue() este apelată:

 class User { var email: String by Delegates.observable("") { prop, old, new -> //handle the change from old to new value } }

Vetoabil

Acest delegat standard este un tip special de observabil care vă permite să decideți dacă o nouă valoare atribuită unei proprietăți va fi stocată sau nu. Poate fi folosit pentru a verifica unele condiții înainte de a atribui o valoare. Ca și în cazul Delegates.observable() , acceptă doi parametri: valoarea inițială și o funcție.

Diferența este că funcția returnează o valoare booleană. Dacă returnează true , noua valoare atribuită proprietății va fi stocată sau, în caz contrar, va fi eliminată.

 var positiveNumber = Delegates.vetoable(0) { d, old, new -> new >= 0 }

Exemplul dat va stoca numai numere pozitive care sunt atribuite proprietății.

Pentru mai multe detalii, consultați documentația oficială.

Caracteristica #9: Maparea unui obiect pe o hartă

Un caz comun de utilizare este stocarea valorilor proprietăților în interiorul unei hărți. Acest lucru se întâmplă adesea în aplicațiile care funcționează cu API-uri RESTful și analizează obiecte JSON. În acest caz, o instanță de hartă poate fi utilizată ca delegat pentru o proprietate delegată. Un exemplu din documentația oficială:

 class User(val map: Map<String, Any?>) { val name: String by map val age: Int by map }

În acest exemplu, User are un constructor primar care preia o hartă. Cele două proprietăți vor prelua valorile din hartă care sunt mapate sub chei care sunt egale cu numele proprietăților:

 val user = User(mapOf( "name" to "John Doe", "age" to 25 ))

Proprietății nume a noii instanțe de utilizator i se va atribui valoarea „John Doe” și proprietății de vârstă valoarea 25.

Acest lucru funcționează și pentru proprietățile var în combinație cu MutableMap :

 class MutableUser(val map: MutableMap<String, Any?>) { var name: String by map var age: Int by map }

Caracteristica #10: Colecții și operațiuni funcționale

Cu suportul pentru lambda din Kotlin, colecțiile pot fi aduse la un nou nivel.

În primul rând, Kotlin distinge între colecțiile mutabile și imuabile. De exemplu, există două versiuni de interfață Iterable :

  • Iterabil
  • MutabilIterabil

Același lucru este valabil și pentru interfețele Collection , List , Set și Map .

De exemplu, aceasta any operație returnează true dacă cel puțin un element se potrivește cu predicatul dat:

 val list = listOf(1, 2, 3, 4, 5, 6) assertTrue(list.any { it % 2 == 0 })

Pentru o listă extinsă de operațiuni funcționale care pot fi efectuate pe colecții, consultați această postare de blog.

Concluzie

Tocmai am zgâriat suprafața a ceea ce oferă Kotlin. Pentru cei interesați să citească și să învețe mai multe, verificați:

  • Postările și cartea lui Antonio Leiva pe blogul Kotlin.
  • Documentație oficială și tutoriale de la JetBrains.

Pentru a rezuma, Kotlin vă oferă posibilitatea de a economisi timp atunci când scrieți aplicații native Android utilizând o sintaxă intuitivă și concisă. Este încă un limbaj de programare tânăr, dar în opinia mea, acum este suficient de stabil pentru a fi folosit pentru construirea de aplicații de producție.

Beneficiile utilizării Kotlin:

  • Suportul de la Android Studio este perfect și excelent.
  • Este ușor să convertiți un proiect Java existent în Kotlin.
  • Codul Java și Kotlin pot coexista în același proiect.
  • Nu există nicio suprasarcină de viteză în aplicație.

Dezavantaje:

  • Kotlin își va adăuga bibliotecile la .apk -ul generat, astfel încât dimensiunea finală a .apk -ului va fi cu aproximativ 300 KB mai mare.
  • Dacă este abuzată, supraîncărcarea operatorului poate duce la cod de necitit.
  • IDE și Autocomplete se comportă puțin mai lent atunci când lucrează cu Kotlin decât cu proiectele Android Java pur.
  • Timpul de compilare poate fi puțin mai lung.