Kotlin ist eine moderne Programmiersprache, die Java-Bytecode kompiliert. Es ist kostenlos und Open Source und verspricht, die Kodierung für Android noch mehr Spaß zu machen.
In dem vorherigen Artikel haben Sie Informationen zu Sortimenten und Sammlungen in Kotlin erhalten. In diesem Lernprogramm lernen Sie die Sprache weiterhin, indem wir uns ansehen, wie Code mit Paketen organisiert wird, und fahren dann mit einer Einführung in die Funktionen von Kotlin fort.
Wenn Sie mit Java vertraut sind, wissen Sie, dass Java Pakete verwendet, um verwandte Klassen zu gruppieren. zum Beispiel die java.util
Paket hat eine Reihe nützlicher Dienstklassen. Pakete werden mit deklariert Paket
Schlüsselwort und jede Kotlin-Datei mit einem Paket
Deklaration am Anfang kann Deklarationen von Klassen, Funktionen oder Schnittstellen enthalten.
Wenn Sie den Code unten betrachten, haben wir ein Paket deklariert com.chikekotlin.projectx
Verwendung der Paket
Stichwort. Wir haben auch eine Klasse deklariert Meine Klasse
(In zukünftigen Beiträgen werden wir in Kotlin Klassen besprechen) in diesem Paket.
Paket com.chikekotlin.projectx-Klasse MyClass
Nun der vollständig qualifizierte Name für die Klasse Meine Klasse
ist com.chikekotlin.projectx.MyClass
.
Paket com.chikekotlin.projectx fun saySomething (): String return "Wie weit?"
Im obigen Code haben wir eine Top-Level-Funktion erstellt (wir werden dies in Kürze tun). So ähnlich wie Meine Klasse
, der vollständig qualifizierte Name für die Funktion Sag etwas()
ist com.chikekotlin.projectx.saySomething
.
In Kotlin verwenden wir die einführen
Deklaration, damit der Compiler die zu importierenden Klassen, Funktionen, Interfaces oder Objekte finden kann. In Java hingegen können Funktionen, Klassen oder Interfaces nur für Methoden direkt importiert werden.
Wir gebrauchen einführen
Zugriff auf eine Funktion, Schnittstelle, Klasse oder ein Objekt außerhalb des Pakets, in dem es deklariert wurde.
import com.chikekotlin.projectx.saySomething fun main (args: Array) saySomething () // druckt "Wie weit?"
Im obigen Code-Snippet haben wir die Funktion importiert Sag etwas()
aus einem anderen Paket, und dann haben wir diese Funktion ausgeführt.
Kotlin unterstützt auch den Import von Platzhaltern mithilfe von *
Operator. Dadurch werden alle im Paket deklarierten Klassen, Schnittstellen und Funktionen gleichzeitig importiert. Dies wird jedoch nicht empfohlen. Normalerweise sollten Sie Ihre Importe jedoch explizit machen.
Import von com.chikekotlin.projectx. *
Wenn Sie Bibliotheken mit widersprüchlichen Klassen- oder Funktionsnamen haben (z. B. deklarieren sie jeweils eine Funktion mit demselben Namen), können Sie das verwenden wie
Schlüsselwort, um der importierten Entität einen temporären Namen zu geben.
import com.chikekotlin.projectx.saySomething import com.chikekotlin.projecty.saySomething als projectYSaySomething Spaß main (args: Array) projectYSaySomething ()
Beachten Sie, dass der temporäre Name nur in der Datei verwendet wird, in der er zugewiesen wurde.
Eine Funktion gruppiert eine Reihe von Codeanweisungen, die eine Aufgabe ausführen. Die Details der Implementierung der Funktion sind dem Aufrufer verborgen.
In Kotlin werden Funktionen mithilfe von definiert Spaß
Schlüsselwort, wie im folgenden Beispiel gezeigt:
fun hallo (name: String): String return "Hello $ name" val message = hallo ("Chike") print (message) // druckt "Hello Chike"
Im obigen Code haben wir eine einfache Funktion definiert Hallo()
mit einem einzigen Parameter Name
vom Typ String
. Diese Funktion gibt a zurück String
Art. Das Parameterdefinitionsformat für Funktionen lautet name: typ
, z.B. Alter: Int
, Preis: Doppel
, Student: StudentClass
.
fun hallo (name: String): unit print ("Hallo $ name") hallo ("Chike") // druckt "Hello Chike"
Die obige Funktion ist der vorherigen ähnlich, beachte jedoch, dass diese einen Rückgabetyp hat Einheit
. Da diese Funktion keinen signifikanten Wert an uns zurückgibt, wird lediglich eine Nachricht ausgegeben. Der Rückgabetyp ist Einheit
standardmäßig. Einheit
ist ein Kotlin-Objekt (wir werden in späteren Beiträgen auf Kotlin-Objekte eingehen), das dem ähnlich ist Leere
Typen in Java und C.
public object Unit überschreiben Spaß toString () = "kotlin.Unit"
Beachten Sie, dass Sie den Rückgabetyp nicht explizit als deklarieren Einheit
, Der Typ wird vom Compiler abgeleitet.
fun hallo (name: String) // kompiliert trotzdem print ("Hello $ name")
Einzeilige oder einzeilige Funktionen sind Funktionen, die nur einzelne Ausdrücke sind. In dieser Funktion entfernen wir die Zahnspange und verwenden die =
Symbol vor dem Ausdruck. Mit anderen Worten, wir werden den Funktionsblock los.
fun calKreisumfang (Radius: Double): Double return (2 * Math.PI) * radius
Die obige Funktion kann in einer einzigen Zeile verkürzt werden:
fun calKreisumfang (Radius: Double) = (2 * Math.PI) * Radius
Wenn Sie die aktualisierte Funktion oben betrachten, sehen Sie, dass wir unseren Code durch das Entfernen der geschweiften Klammern präziser gemacht haben , das
Rückkehr
Schlüsselwort und auch der Rückgabetyp (der vom Compiler abgeleitet wird).
Sie können den Rückgabetyp dennoch angeben, um genauer zu sein, wenn Sie möchten.
fun calKreisumfang (Radius: Double): Double = (2 * Math.PI) * Radius
Benannte Parameter ermöglichen besser lesbare Funktionen, indem sie die Parameter benennen, die beim Aufruf an eine Funktion übergeben werden.
Im folgenden Beispiel haben wir eine Funktion erstellt, die meinen vollständigen Namen ausgibt.
fun sayMyFullName (firstName: String, lastName: String, middleName: String): Einheit print ("Mein vollständiger Name ist $ firstName $ middleName $ lastName");
Um die Funktion oben auszuführen, würden wir sie einfach so nennen:
sayMyFullName ("Chike", "Nnamdi", "Mgbemena")
Wenn Sie den Funktionsaufruf oben betrachten, wissen wir nicht was String
Typargumente entsprechen den Funktionsparametern (obwohl einige IDEs wie IntelliJ IDEA uns dabei helfen können). Benutzer der Funktion müssen sich die Funktionssignatur (oder den Quellcode) oder die Dokumentation ansehen, um zu erfahren, was jedem Parameter entspricht.
sayMyFullName (firstName = "Chike", middleName = "Nnamdi", lastName = "Mgbemena")
Im zweiten Funktionsaufruf oben haben wir die Parameternamen vor den Argumentwerten angegeben. Sie sehen, dass dieser Funktionsaufruf klarer und lesbarer ist als der vorherige. Diese Art, Funktionen aufzurufen, verringert die Wahrscheinlichkeit von Fehlern, die auftreten können, wenn Argumente desselben Typs versehentlich ausgetauscht werden.
Der Aufrufer kann auch die Reihenfolge der Parameter mithilfe von benannten Parametern ändern. Zum Beispiel:
sayMyFullName (lastName = "Mgbemena", middleName = "Nnamdi", firstName = "Chike") // wird immer noch kompiliert
Im obigen Code haben wir die Argumentposition von ersetzt Vorname
mit dem Nachname
. Die Reihenfolge der Argumente spielt bei benannten Parametern keine Rolle, da der Compiler jeden von ihnen dem rechten Funktionsparameter zuordnet.
In Kotlin können wir für jeden Parameter einen Funktionsvorgabewert angeben. Diese Standardwerte werden verwendet, wenn den Argumenten während des Funktionsaufrufs nichts zugewiesen wird. Um dies in Java zu tun, müssen wir verschiedene überladene Methoden erstellen.
Hier in unserem calCumfum ()
Wir haben die Methode geändert, indem wir einen Standardwert für die Pi
Parameter-Math.PI
, eine Konstante aus dem java.lang.Math
Paket.
fun calKreisumfang (Radius: Double, pi: Double = Math.PI): Double = (2 * pi) * Radius
Wenn wir diese Funktion aufrufen, können wir entweder unseren ungefähren Wert für übergeben Pi
oder verwenden Sie die Standardeinstellung.
print (calCircumference (24.0)) // verwendet den Standardwert für PI und druckt 150.79644737231007 print (calCum- mference (24.0, 3.14)) // übergibt den Wert für PI und druckt 150.72
Lassen Sie uns ein anderes Beispiel sehen.
fun printName (firstName: String, middleName: String = "N / A", lastName: String) println ("Vorname: $ firstName - zweiter Vorname: $ middleName - Nachname: $ lastName")
Im folgenden Code haben wir versucht, die Funktion aufzurufen, sie wird jedoch nicht kompiliert:
printName ("Chike", "Mgbemena") // wird nicht kompiliert
Beim Funktionsaufruf oben übergebe ich meinen Vornamen und Nachnamen an die Funktion und hoffe, dass der Standardwert für den zweiten Vornamen verwendet wird. Dies wird jedoch nicht kompiliert, da der Compiler verwirrt ist. Es weiß nicht, was das Argument "Mgbemena" ist - ist es für die zweiter Vorname
oder der Nachname
Parameter?
Um dieses Problem zu lösen, können wir benannte Parameter und Standardparameter kombinieren.
printName ("Chike", lastName = "Mgbemena") // wird jetzt kompiliert
Da Java keine Standardparameterwerte in Methoden unterstützt, müssen Sie alle Parameterwerte explizit angeben, wenn Sie eine Kotlin-Funktion von Java aus aufrufen. Kotlin stellt uns jedoch die Funktionalität zur Verfügung, die es den Java-Aufrufern erleichtert, indem sie die Kotlin-Funktion mit Anmerkungen versehen @JvmOverloads
. Diese Anmerkung weist den Kotlin-Compiler an, die Java-überladenen Funktionen für uns zu generieren.
Im folgenden Beispiel haben wir das kommentiert calCirumference ()
Funktion mit @JvmOverloads
.
@JvmÜberlädt fun calCircumference (Radius: Double, pi: Double = Math.PI): Double = (2 * pi) * Radius
Der folgende Code wurde vom Kotlin-Compiler generiert, sodass Java-Aufrufer auswählen können, welcher aufgerufen werden soll.
// Java double calCircumference (Doppelradius, Doppel-Pi); doppelter cal-Umfang (doppelter Radius);
In der zuletzt generierten Java-Methodendefinition wird die Pi
Parameter wurde ausgelassen. Das bedeutet, dass die Methode den Standard verwendet Pi
Wert.
In Java können wir eine Methode erstellen, um eine nicht spezifizierte Anzahl von Argumenten zu erhalten, indem eine Ellipse eingefügt wird (…
) nach einem Typ in der Parameterliste der Methode. Dieses Konzept wird auch von Kotlin - Funktionen mit der Verwendung von unterstützt Vararg
Modifikator gefolgt vom Parameternamen.
fun printInts (vararg ints: Int): Die Einheit for (n in ints) print ("$ n \ t") printInts (1, 2, 3, 4, 5, 6) // druckt 1 2 3 4 5 6
Das Vararg
Mit dem Modifikator können Anrufer eine durch Kommas getrennte Liste von Argumenten übergeben. Hinter den Kulissen wird diese Liste von Argumenten in ein Array eingefügt.
Wenn eine Funktion mehrere Parameter hat, wird die Vararg
Parameter ist normalerweise der letzte. Es ist auch möglich, Parameter nach dem zu haben Vararg
, Sie müssen jedoch benannte Parameter verwenden, um sie beim Aufruf der Funktion anzugeben.
fun printNumbers (myDouble: Double, myFloat: Float, Variationen in Int: Int) println (myDouble) println (myFloat) für (in n) print ("$ n \ t") printNumbers (1.34, 4.4F, 2, 3, 4, 5, 6) // wird kompiliert
Im obigen Code beispielsweise der Parameter mit der Vararg
Der Modifizierer befindet sich an der letzten Stelle in einer Liste mit mehreren Parametern (dies ist das, was wir normalerweise tun). Was aber, wenn wir es nicht in der letzten Position haben wollen? Im folgenden Beispiel befindet es sich in der zweiten Position.
fun printNumbers (myDouble: Double, Variationen: Int, myFloat: Float) println (myDouble) println (myFloat) für (n in Ints) print ("$ n \ t") printNumbers (1.34, 2, 3 , 4, 5, 6, myFloat = 4.4F) // wird printNumbers kompilieren (1.34, ints = 2, 3, 4, 5, 6, myFloat = 4.4F) // wird keine PrintNumbers kompilieren (myDouble = 1.34, ints = 2, 3, 4, 5, 6, myFloat = 4.4F) // wird auch nicht kompiliert
Wie Sie im aktualisierten Code oben sehen können, haben wir benannte Argumente für den letzten Parameter verwendet, um das Problem zu lösen.
Nehmen wir an, wir möchten eine ganze Reihe von Ganzzahlen an unsere übergeben printNumbers ()
Funktion. Die Funktion erwartet jedoch, dass die Werte in einer Liste von Parametern abgewickelt werden. Wenn Sie versuchen, das Array direkt an zu übergeben printNumbers ()
, Sie werden sehen, dass es nicht kompiliert wird.
val intsArray: IntArray = intArrayOf (1, 3, 4, 5) printNumbers (1.34, intsArray, myFloat = 4.4F) // wird nicht kompiliert
Um dieses Problem zu lösen, müssen Sie den Spread-Operator verwenden *
. Dieser Operator entpackt das Array und übergibt die einzelnen Elemente als Argumente an die Funktion für uns.
val intsArray: IntArray = intArrayOf (1, 3, 4, 5) printNumbers (1.34, * intsArray, myFloat = 4.4F) // wird jetzt kompiliert
Durch Einfügen des Spread-Operators *
vor intsArray
In der Argumentliste der Funktion wird der Code jetzt kompiliert und erzeugt dasselbe Ergebnis, als hätten wir die Elemente von übergeben intsArray
als durch Kommas getrennte Liste von Argumenten.
Manchmal möchten wir mehrere Werte aus einer Funktion zurückgeben. Eine Möglichkeit ist die Verwendung der Paar
Geben Sie Kotlin ein, um eine zu erstellen Paar
und dann zurückgeben. Diese Paar
Die Struktur umfasst zwei Werte, auf die später zugegriffen werden kann. Dieser Kotlin-Typ kann alle Typen akzeptieren, die Sie seinem Konstruktor bereitstellen. Außerdem müssen die beiden Typen nicht gleich sein.
fun getUserNameAndState (id: Int): Paarrequired (id> 0, "Fehler: id ist kleiner als 0") val userNames: Map = mapOf (101 nach "Chike", 102 nach "Segun", 104 nach "Jane") val userStates: Map = mapOf (101 an "Lagos", 102 an "Imo", 104 an "Enugu") val benutzername = benutzername [id] val benutzerstatus = benutzerstatus [id] Rückgabepaar (benutzername, benutzerstatus)
In der obigen Funktion haben wir eine neue erstellt Paar
durch die Weitergabe der Nutzername
und userState
Variablen als erstes bzw. zweites Argument an den Konstruktor übergeben und dann zurückgegeben Paar
an den anrufer.
Eine weitere Sache ist, dass wir eine aufgerufene Funktion verwendet haben benötigen()
in dem getUserNameAndState ()
Funktion. Diese Hilfsfunktion aus der Standardbibliothek wird verwendet, um unseren Funktionsaufrufen eine Vorbedingung zu geben, oder eine IllegalArgumentException
wird geworfen (wir werden in einem zukünftigen Beitrag Ausnahmen in Kotlin besprechen). Das optionale zweite Argument zu benötigen()
ist ein Funktionsliteral, das eine Nachricht zurückgibt, die angezeigt wird, wenn die Ausnahme ausgelöst wird. Zum Beispiel den Aufruf von getUserNameAndState ()
Funktion und Weitergabe -1
als Argument dazu wird auslösen:
Paar
val userNameAndStatePair: Paar= getUserNameAndState (101) println (userNameAndStatePair.first) // Chike println (userNameAndStatePair.second) // Lagos
Im obigen Code haben wir auf den ersten und den zweiten Wert aus dem zugegriffen Paar
tippen Sie mit seiner zuerst
und zweite
Eigenschaften.
Es gibt jedoch einen besseren Weg, dies zu tun: Zerstörung.
val (name, state) = getUserNameAndState (101) println (name) // Chike println (state) // Lagos
Was wir im aktualisierten Code oben getan haben, ist die direkte Zuweisung der ersten und zweiten Werte der zurückgegebenen Werte Paar
Geben Sie die Variablen ein Name
und Zustand
beziehungsweise. Diese Funktion wird aufgerufen Zerstörungserklärung.
Nun, was ist, wenn Sie drei Werte gleichzeitig zurückgeben möchten? Kotlin liefert uns einen anderen nützlichen Typ namens Verdreifachen
.
fun getUserNameStateAndAge (id: Int): Dreifachrequired (id> 0, "id ist kleiner als 0") val userNames: Map = mapOf (101 nach "Chike", 102 nach "Segun", 104 nach "Jane") val userStates: Map = mapOf (101 an "Lagos", 102 an "Imo", 104 an "Enugu") val userName = userNames [id] val userState = userStates [id] val userAge = 6 gibt Triple zurück (userNames [id], userStates [id.) ], userAge) val (Name, Status, Alter) = getUserNameStateAndAge (101) println (name) // Chike println (state) // Lagos println (age) // 6
Ich bin sicher, einige von Ihnen fragen sich, was zu tun ist, wenn Sie mehr als drei Werte zurückgeben möchten. Die Antwort darauf wird in einem späteren Beitrag sein, wenn wir die Datenklassen von Kotlin diskutieren.
In diesem Lernprogramm haben Sie die Pakete und grundlegenden Funktionen der Programmiersprache Kotlin kennen gelernt. Im nächsten Tutorial der Kotlin From Scratch-Serie erfahren Sie mehr über Funktionen in Kotlin. Bis bald!
Um mehr über die Kotlin-Sprache zu lernen, empfehle ich die Kotlin-Dokumentation. Auf Envato Tuts finden Sie auch einige unserer anderen Android-Apps zur Entwicklung von Apps+!