Kotlin este un limbaj de programare modern care se compilează la Java bytecode. Este gratuit și open source, și promite să facă codificarea pentru Android chiar mai distractiv.
În articolul precedent, ați aflat despre intervalele și colecțiile din Kotlin. În acest tutorial, vom continua să învățăm limba, urmărindu-ne cum să organizăm codul folosind pachetele și apoi să mergem la o introducere a funcțiilor din Kotlin.
Dacă sunteți familiarizat cu Java, știți că Java utilizează pachete pentru a grupa clase conexe; de exemplu, java.util
pachetul are un număr de clase utilitare utile. Pachetele sunt declarate cu pachet
cuvânt cheie, și orice fișier Kotlin cu un pachet
declarația de la început poate conține declarații de clase, funcții sau interfețe.
Privind la codul de mai jos, am declarat un pachet com.chikekotlin.projectx
folosind pachet
cuvinte cheie. De asemenea, am declarat o clasă Clasa mea
(vom discuta clasele din Kotlin în posturile viitoare) din acest pachet.
pachet com.chikekotlin.projectx clasa MyClass
Acum, numele complet calificat pentru clasă Clasa mea
este com.chikekotlin.projectx.MyClass
.
pachet com.chikekotlin.projectx distracție saySomething (): String retur "Cât de departe?"
În codul de mai sus, am creat o funcție de nivel superior (vom ajunge la asta în scurt timp). Deci, la fel Clasa mea
, numele complet calificat al funcției spune ceva()
este com.chikekotlin.projectx.saySomething
.
În Kotlin, folosim import
declarație pentru a permite compilatorului să localizeze clasele, funcțiile, interfețele sau obiectele ce urmează a fi importate. În Java, pe de altă parte, nu putem importa direct funcții sau clase sau interfețe numai pentru metode.
Folosim import
pentru a accesa o funcție, o interfață, o clasă sau un obiect în afara pachetului unde a fost declarată.
import com.chikekotlin.projectx.sayCeva distractiv principal (args: Array) saySomething () // va tipări "Cât de departe?"
În fragmentul de cod de mai sus, am importat funcția spune ceva()
dintr-un alt pachet, iar apoi am executat acea funcție.
Kotlin susține, de asemenea, importurile de metacaractere folosind *
operator. Aceasta va importa toate clasele, interfețele și funcțiile declarate în pachet simultan. Acest lucru nu este recomandat, totuși, este de obicei mai bine să faceți importurile dvs. explicite.
import com.chikekotlin.projectx. *
Când aveți biblioteci care au nume de clasă sau funcții conflictuale (de exemplu, fiecare declară o funcție cu același nume), puteți utiliza la fel de
pentru a da o entitate importată un nume temporar.
import com.chikekotlin.projectx.sayCeva import com.chikekotlin.projecty.sayCeva ca proiectYSaySomething distractiv principal (args: Array) projectYSaySomething ()
Rețineți că numele temporar este utilizat numai în fișierul în care a fost atribuit.
O funcție grupează o serie de declarații de cod care execută o sarcină. Detaliile implementării funcției sunt ascunse de apelant.
În Kotlin, funcțiile sunt definite folosind distracţie
cuvânt cheie, după cum se arată în următorul exemplu:
distracție salut (nume: String): String return "Hello $ name" val mesaj = hello ("Chike"
În codul de mai sus, am definit o funcție simplă Salut()
cu un singur parametru Nume
de tip Şir
. Această funcție returnează a Şir
tip. Formatul de definire a parametrilor pentru funcții este nume: tip
, de exemplu. vârstă: Int
, Preț: Dublă
, student: StudentClass
.
distracție hello (nume: String): unitate print ("Hello $ name") hello ("Chike") // va imprima "Hello Chike"
Funcția de mai sus este similară cu cea anterioară, însă observați că aceasta are un tip de returnare Unitate
. Deoarece această funcție nu ne aduce nicio valoare semnificativă - imprimă doar un mesaj - tipul de retur este Unitate
în mod implicit. Unitate
este un obiect Kotlin (vom discuta obiecte Kotlin în posturi ulterioare) care este similar cu neavenit
tipuri în Java și C.
obiect obiect public override fun toString () = "kotlin.Unit"
Rețineți că, dacă nu declarați în mod explicit tipul de returnare Unitate
, tipul este dedus de compilator.
distracție salut (nume: String) // va compila în continuare imprimarea ("Hello $ name")
Funcțiile single-line sau one-line sunt funcții care sunt doar expresii singulare. În această funcție, scapăm de bretele și folosim =
simbol înainte de expresie. Cu alte cuvinte, scapăm de blocul de funcții.
Distracție calCircumference (rază: Dublu): Dublă întoarcere (2 * Math.PI) * rază
Funcția de mai sus poate fi redusă într-o singură linie:
Distracție calCircumference (rază: Double) = (2 * Math.PI) * raza
Privind la funcția actualizată de mai sus, puteți vedea că am făcut codul nostru mai concis prin îndepărtarea bretelelor ,
întoarcere
cuvântul cheie și, de asemenea, tipul de retur (care este dedus de compilator).
Încă puteți include tipul de retur pentru a fi mai explicit dacă doriți.
distracție calCircumferință (rază: dublă): Dublă = (2 * Math.PI) * raza
Parametrii numiți permit funcții mai ușor de citit, prin denumirea parametrilor care sunt transmise unei funcții atunci când sunt apelate.
În următorul exemplu, am creat o funcție care imprimă numele meu complet.
distracție sayMyFullName (firstName: String, lastName: String, middleName: String): Unit print ("Numele meu complet este $ firstName $ middleName $ lastName");
Pentru a executa funcția de mai sus, am fi numit așa:
sayMyFullName ("Chike", "Nnamdi", "Mgbemena")
Privind la chemarea funcției de mai sus, nu știm ce Şir
introduceți argumentele care corespund parametrilor funcției (deși unele IDE-uri precum IntelliJ IDEA ne pot ajuta). Utilizatorii funcției vor trebui să caute semnătura funcției (sau codul sursă) sau documentația pentru a ști ce corespund fiecărui parametru.
sayMyFullName (numeName = "Chike", middleName = "Nnamdi", lastName = "Mgbemena")
În al doilea apel de funcții de mai sus, am furnizat numele parametrilor înainte de valorile argumentului. Puteți vedea că această funcție este mai clară și mai lizibilă decât cea precedentă. Acest mod de apelare a funcțiilor ajută la reducerea posibilității de bug-uri care pot apărea atunci când argumentele de același tip sunt schimbate din greșeală.
Apelantul poate modifica, de asemenea, ordinea parametrilor utilizând parametrii numiți. De exemplu:
sayMyFullName (lastName = "Mgbemena", middleName = "Nnamdi", firstName = "Chike") // va compila încă
În codul de mai sus, am schimbat poziția argumentului Nume
cu numele de familie
. Ordinea argumentului nu contează cu parametrii numiți, deoarece compilatorul va cartografia fiecare dintre ele la parametrul funcției corecte.
În Kotlin, putem oferi o valoare implicită a funcției pentru oricare dintre parametrii săi. Aceste valori implicite sunt utilizate dacă nimic nu este atribuit argumentelor în timpul apelului funcției. Pentru a face acest lucru în Java, ar trebui să creați metode de încărcare diferite.
Aici, în nostru calCircumference ()
, am modificat metoda adăugând o valoare implicită pentru pi
parametru-Math.PI
, o constantă de la java.lang.Math
pachet.
Distracție calCircumferință (rază: Dublă, pi: Dublă = Math.PI): Dublă = (2 * pi) * raza
Când numim această funcție, putem trece valoarea noastră aproximată pi
sau utilizați setarea implicită.
print (calCircumference (24.0)) // valoarea implicită folosită pentru PI și tipărite 150.79644737231007 print (calCircumference (24.0, 3.14)) // valoarea trecută pentru PI și printuri 150.72
Să vedem un alt exemplu.
distracție printName (numeName: String, middleName: String = "N / A", lastName: String) println (nume: $ firstName - nume mijloc: $ middleName -
În următorul cod, am încercat să apelăm funcția, dar nu se va compila:
printName ("Chike", "Mgbemena") // nu se va compila
În apelul de funcții de mai sus, transmit numele și prenumele funcției și sperând să utilizez valoarea implicită pentru numele intermediar. Dar acest lucru nu se va compila deoarece compilatorul este confuz. Nu știe care este argumentul "Mgbemena" - este pentru al doilea nume
sau numele de familie
parametru?
Pentru a rezolva această problemă, putem combina parametrii numiți și parametrii impliciți.
printName ("Chike", lastName = "Mgbemena") // se va compila acum
Dat fiind că Java nu suportă valori de parametru implicite în metode, va trebui să specificați explicit toate valorile parametrilor atunci când apelați o funcție Kotlin din Java. Dar Kotlin ne oferă funcționalitatea pentru a facilita apelanții Java prin adnotarea funcției Kotlin @JvmOverloads
. Această adnotare va instrui compilatorul Kotlin să genereze funcțiile Java supraîncărcate pentru noi.
În următorul exemplu, am adnotat calCirumference ()
funcția cu @JvmOverloads
.
@ JvmOverloads distracție calCircumference (rază: Dublă, pi: Dublă = Math.PI): Dublă = (2 * pi) * raza
Următorul cod a fost generat de compilatorul Kotlin, astfel încât apelanții Java pot alege apoi pe cine să sune.
// Java double calCircumference (raza dublă, dublă pi); dublu calCircumferință (rază dublă);
În ultima definiție a metodei Java generată, pi
parametru a fost omis. Aceasta înseamnă că metoda va utiliza valoarea implicită pi
valoare.
În Java, putem crea o metodă pentru a primi un număr nespecificat de argumente prin includerea unei elipse (...
) după un tip din lista de parametri a metodei. Acest concept este, de asemenea, susținut de funcțiile Kotlin cu utilizarea vararg
modificator urmat de numele parametrului.
Funcții de tipărire fun (vararg ints: Int): Unitatea pentru (n in t) print ("$ n \ t") printInts (1, 2, 3, 4, 5, 6) 4 5 6
vararg
Modificatorul permite apelanților să treacă printr-o listă de argumente separate prin virgulă. În spatele scenei, această listă de argumente va fi înfășurată într-o matrice.
Atunci când o funcție are mai mulți parametri, vararg
parametrul este de obicei ultimul. De asemenea, este posibil să existe parametri după vararg
, dar va trebui să utilizați parametri numiți pentru a le specifica atunci când apelați funcția.
distracție printNumbers (myDouble: Double, myFloat: Float, vararg ints: Int) println (myDouble) println (myFloat) pentru n ints) print (" 2, 3, 4, 5, 6) // va compila
De exemplu, în codul de mai sus, parametrul cu vararg
Modificatorul se află în ultima poziție într-o listă de parametri multiple (aceasta este ceea ce facem de obicei). Dar dacă nu o dorim în ultima poziție? În exemplul următor, se află în a doua poziție.
Distribuitorul (myDouble: Double, vararg ints: Int, myFloat: Float) println (myDouble) println (myFloat) pentru n in ints) print ("$ n \ t") printNumbers (1.34, 2, 3 , 4, 5, 6, myFloat = 4.4F) // va compila PrintNumbers (1.34, ints = 2, 3, 4, 5, 6, myFloat = 4.4F) // nu va compila PrintNumbers (myDouble = 2, 3, 4, 5, 6, myFloat = 4.4F) // nu se va compila, de asemenea
După cum puteți observa în codul actualizat de mai sus, am folosit argumente numite pe ultimul parametru pentru a rezolva acest lucru.
Să presupunem că vrem să trecem o serie de numere întregi printNumbers ()
funcţie. Funcția așteaptă însă ca valorile să fie derulate într-o listă de parametri. Dacă încercați să treceți direct matricea printNumbers ()
, veți vedea că nu se va compila.
val intArray: IntArray = intArrayOf (1, 3, 4, 5) printNumbers (1.34, intsArray, myFloat = 4.4F) // nu compila
Pentru a rezolva această problemă, trebuie să folosim operatorul de răspândire *
. Acest operator va despacheta matricea și apoi va transmite elementele individuale ca argumente în funcția pentru noi.
val intarsArray: IntArray = intArrayOf (1, 3, 4, 5) printNumbers (1.34, * intsArray, myFloat = 4.4F) // va compila acum
Introducerea operatorului de distribuire *
în fața intsArray
în lista de argumente a funcției, codul se compilează acum și produce același rezultat ca și cum am fi trecut elementele lui intsArray
ca o listă de argumente separate prin virgulă.
Uneori vrem să returnăm mai multe valori dintr-o funcție. O modalitate este de a utiliza Pereche
tip în Kotlin pentru a crea un Pereche
și apoi returnați-o. Acest Pereche
structura cuprinde două valori care pot fi accesate mai târziu. Acest tip Kotlin poate accepta toate tipurile pe care le furnizați constructorului. Și, mai mult, cele două tipuri nu trebuie nici măcar să fie la fel.
distracție getUserNameAndState (id: Int): Perechenecesită (id> 0, "Eroare: id este mai mică de 0") val userNames: Map = mapOf (101 la "Chike", 102 la "Segun", 104 la "Jane") val userStates: Harta = mapOf (101 la "Lagos", 102 la "Imo", 104 la "Enugu") val userName = userNames [id] val userState = userStates [id] retur Pair (userName, userState)
În funcția de mai sus, am construit un nou Pereche
prin trecerea lui nume de utilizator
și userState
variabilele ca primul și respectiv al doilea argument pentru constructorul său, apoi au returnat acest lucru Pereche
la apelant.
Un alt lucru de observat este că am folosit o funcție numită require ()
în getUserNameAndState ()
funcţie. Această funcție de ajutor din biblioteca standard este utilizată pentru a oferi apelanților noștri funcția o condiție prealabilă pentru a satisface, sau altceva IllegalArgumentException
vor fi aruncate (vom discuta Excepții în Kotlin într-un post viitor). Al doilea argument opțional la require ()
este o funcție literală care returnează un mesaj care va fi afișat dacă excepția este aruncată. De exemplu, sunând la getUserNameAndState ()
funcționare și trecere -1
ca un argument pentru aceasta va declanșa:
Pereche
val userNameAndStatePair: Pereche= getUserNameAndState (101) println (userNameAndStatePair.first) // Chineză println (userNameAndStatePair.second) // Lagos
În codul de mai sus, am accesat prima și a doua valoare din Pereche
tip folosind primul
și al doilea
proprietăţi.
Cu toate acestea, există o modalitate mai bună de a face acest lucru: distrugerea.
val (nume, stare) = getUserNameAndState (101) println (nume) // Chike println (state) // Lagos
Ceea ce am făcut în codul actualizat de mai sus este atribuirea directă a primei și celei de-a doua valori a metodei returnate Pereche
tip la variabile Nume
și stat
respectiv. Această caracteristică este numită declarație de distrugere.
Acum, dacă doriți să reveniți la trei valori simultan? Kotlin ne oferă un alt tip util numit Triplu
.
distracție getUserNameStateAndAge (id: Int): Triplănecesită (id> 0, "id este mai mică de 0") val userNames: Map = mapOf (101 la "Chike", 102 la "Segun", 104 la "Jane") val userStates: Harta = mapOf (101 la "Lagos", 102 la "Imo", 104 la "Enugu") val userName = userNames [id] val userState = userStates [id] val userAge = ], valA (nume, stare, vârstă) = getUserNameStateAndAge (101) println (nume) // Chike println (state) // Lagos println (vârstă) // 6
Sunt sigur că unii dintre voi vă întrebați ce să faceți dacă doriți să reveniți la mai mult de trei valori. Răspunsul pentru acest lucru va fi într-un post mai târziu, când discutăm clasele de date ale lui Kotlin.
În acest tutorial, ați aflat despre pachetele și funcțiile de bază din limba de programare Kotlin. În următorul tutorial din seria Kotlin From Scratch, veți afla mai multe despre funcțiile din Kotlin. Ne vedem în curând!
Pentru a afla mai multe despre limba Kotlin, vă recomand să vizitați documentația Kotlin. Sau verificați câteva dintre celelalte postări pentru dezvoltarea aplicațiilor Android aici pe Envato Tuts+!