Kotlin-Bootcamp für Programmierer 2: Kotlin-Grundlagen

Dieses Codelab ist Teil des Kotlin-Bootcamps für Programmierer. Sie können diesen Kurs am besten nutzen, wenn Sie die Codelabs der Reihe nach durcharbeiten. Je nach Ihrem Wissen können Sie einige Abschnitte möglicherweise überfliegen. Dieser Kurs richtet sich an Programmierer, die eine objektorientierte Sprache kennen und Kotlin lernen möchten.

Einführung

In diesem Codelab lernen Sie die Grundlagen der Programmiersprache Kotlin kennen: Datentypen, Operatoren, Variablen, Kontrollstrukturen und nullable im Vergleich zu nicht nullable Variablen. Dieser Kurs richtet sich an Programmierer, die eine objektorientierte Sprache kennen und Kotlin lernen möchten.

In diesem Kurs wird keine einzelne Beispiel-App entwickelt. Stattdessen sollen die Lektionen Ihr Wissen erweitern, sind aber weitgehend unabhängig voneinander, sodass Sie Abschnitte, mit denen Sie vertraut sind, überspringen können. Um die Beispiele zu veranschaulichen, wird in vielen ein Aquarium verwendet. Wenn Sie die ganze Geschichte des Aquariums sehen möchten, können Sie sich den Udacity-Kurs Kotlin Bootcamp for Programmers ansehen.

Was Sie bereits wissen sollten

  • Projekt in IntelliJ IDEA erstellen
  • So öffnen und führen Sie Code in der REPL (Read-Eval-Print Loop) von Kotlin in IntelliJ IDEA aus (Tools > Kotlin > Kotlin REPL)

Lerninhalte

  • Datentypen, Operatoren und Variablen in Kotlin verwenden
  • Mit booleschen Werten und Bedingungen arbeiten
  • Unterschied zwischen Variablen, die Nullwerte zulassen, und Variablen, die keine Nullwerte zulassen
  • Arrays, Listen und Schleifen in Kotlin

Aufgaben

  • Grundlagen von Kotlin mit der Kotlin-REPL lernen

In dieser Aufgabe lernen Sie Operatoren und Typen in der Programmiersprache Kotlin kennen.

Schritt 1: Numerische Operatoren kennenlernen

  1. Öffnen Sie IntelliJ IDEA, falls es noch nicht geöffnet ist.
  2. Wenn Sie die Kotlin REPL öffnen möchten, wählen Sie Tools > Kotlin > Kotlin REPL aus.

Wie bei anderen Sprachen werden in Kotlin +, -, * und / für Plus, Minus, Mal und Division verwendet. Kotlin unterstützt auch verschiedene Zahlentypen wie Int, Long, Double und Float.

  1. Geben Sie die folgenden Ausdrücke in die REPL ein. Drücken Sie nach jeder Eingabe Control+Enter (Command+Enter auf einem Mac), um das Ergebnis zu sehen.
1+1
⇒ res8: kotlin.Int = 2

53-3
⇒ res9: kotlin.Int = 50

50/10
⇒ res10: kotlin.Int = 5

1.0/2.0
⇒ res11: kotlin.Double = 0.5

2.0*3.5
⇒ res12: kotlin.Double = 7.0

Die Ergebnisse von Operationen behalten die Typen der Operanden bei. Daher gilt: 1/2 = 0, aber 1.0/2.0 = 0.5.

  1. Probieren Sie einige Ausdrücke mit verschiedenen Kombinationen aus Ganz- und Dezimalzahlen aus.
6*50
⇒ res13: kotlin.Int = 300

6.0*50.0
⇒ res14: kotlin.Double = 300.0

6.0*50
⇒ res15: kotlin.Double = 300.0
  1. Rufen Sie einige Methoden für Zahlen auf. In Kotlin werden Zahlen als Primitiven beibehalten, aber Sie können Methoden für Zahlen aufrufen, als wären sie Objekte.
2.times(3)
⇒ res5: kotlin.Int = 6

3.5.plus(4)
⇒ res8: kotlin.Double = 7.5

2.4.div(2)
⇒ res9: kotlin.Double = 1.2

Schritt 2: Typen verwenden

In Kotlin werden keine impliziten Konvertierungen zwischen Zahlentypen vorgenommen. Sie können also keinen Short-Wert direkt einer Long-Variablen oder einen Byte-Wert einer Int-Variablen zuweisen. Das liegt daran, dass die implizite Zahlenkonvertierung eine häufige Fehlerquelle in Programmen ist. Sie können immer Werte unterschiedlicher Typen zuweisen, indem Sie sie umwandeln.

  1. Um einige der möglichen Umwandlungen zu sehen, definieren Sie in der REPL eine Variable vom Typ Int.
val i: Int = 6
  1. Erstellen Sie eine neue Variable und geben Sie den oben gezeigten Variablennamen gefolgt von .to ein.
val b1 = i.to

IntelliJ IDEA zeigt eine Liste möglicher Vervollständigungen an. Die automatische Vervollständigung funktioniert für Variablen und Objekte beliebigen Typs.

  1. Wählen Sie toByte() aus der Liste aus und geben Sie die Variable aus.
val b1 = i.toByte()
println(b1)
⇒ 6
  1. Weisen Sie Variablen unterschiedlicher Typen einen Byte-Wert zu.
val b2: Byte = 1 // OK, literals are checked statically
println(b2)
⇒ 1

val i1: Int = b2
⇒ error: type mismatch: inferred type is Byte but Int was expected

val i2: String = b2
⇒ error: type mismatch: inferred type is Byte but String was expected

val i3: Double = b2
⇒ error: type mismatch: inferred type is Byte but Double was expected
  1. Bei den Zuweisungen, bei denen Fehler aufgetreten sind, sollten Sie es stattdessen mit der Übertragung versuchen.
val i4: Int = b2.toInt() // OK!
println(i4)
⇒ 1

val i5: String = b2.toString()
println(i5)
⇒ 1

val i6: Double = b2.toDouble()
println(i6)
⇒ 1.0
  1. Um lange numerische Konstanten lesbarer zu machen, können Sie in Kotlin Unterstriche in die Zahlen einfügen, wo es für Sie sinnvoll ist. Versuchen Sie es mit anderen numerischen Konstanten.
val oneMillion = 1_000_000
val socialSecurityNumber = 999_99_9999L
val hexBytes = 0xFF_EC_DE_5E
val bytes = 0b11010010_01101001_10010100_10010010

Schritt 3: Wert von Variablentypen ermitteln

Kotlin unterstützt zwei Arten von Variablen: veränderliche und unveränderliche. Mit val können Sie einen Wert einmal zuweisen. Wenn Sie versuchen, etwas noch einmal zuzuweisen, erhalten Sie eine Fehlermeldung. Mit var können Sie einen Wert zuweisen und ihn später im Programm ändern.

  1. Definieren Sie Variablen mit val und var und weisen Sie ihnen dann neue Werte zu.
var fish = 1
fish = 2
val aquarium = 1
aquarium = 2
⇒ error: val cannot be reassigned

Sie können fish einen Wert zuweisen und ihm dann einen neuen Wert zuweisen, da es mit var definiert ist. Wenn Sie versuchen, aquarium einen neuen Wert zuzuweisen, wird ein Fehler ausgegeben, da die Variable mit val definiert ist.

Der Typ, den Sie in einer Variablen speichern, wird abgeleitet, wenn der Compiler ihn aus dem Kontext ermitteln kann. Sie können den Typ einer Variablen immer explizit mit der Doppelpunktnotation angeben.

  1. Definieren Sie einige Variablen und geben Sie den Typ explizit an.
var fish: Int = 12
var lakes: Double = 2.5

Sobald ein Typ von Ihnen oder dem Compiler zugewiesen wurde, können Sie ihn nicht mehr ändern. Andernfalls wird ein Fehler ausgegeben.

Schritt 4: Informationen zu Strings

Strings in Kotlin funktionieren weitgehend wie Strings in anderen Programmiersprachen. Sie verwenden " für Strings und ' für einzelne Zeichen. Strings können mit dem Operator + verkettet werden. Sie können Stringvorlagen erstellen, indem Sie sie mit Werten kombinieren. Der Name $variable wird durch den Text ersetzt, der den Wert darstellt. Das wird als Variableninterpolation bezeichnet.

  1. Erstellen Sie eine String-Vorlage.
val numberOfFish = 5
val numberOfPlants = 12
"I have $numberOfFish fish" + " and $numberOfPlants plants"
⇒ res20: kotlin.String = I have 5 fish and 12 plants
  1. Erstellen Sie eine String-Vorlage mit einem Ausdruck. Wie in anderen Sprachen kann der Wert das Ergebnis eines Ausdrucks sein. Verwenden Sie geschweifte Klammern {}, um den Ausdruck zu definieren.
"I have ${numberOfFish + numberOfPlants} fish and plants"
⇒ res21: kotlin.String = I have 17 fish and plants

In dieser Aufgabe lernen Sie boolesche Werte und das Prüfen von Bedingungen in der Programmiersprache Kotlin kennen. Wie andere Sprachen hat Kotlin boolesche Werte und boolesche Operatoren wie „kleiner als“, „gleich“, „größer als“ usw. (<, ==, >, !=, <=, >=).

  1. Schreiben Sie eine if- oder else-Erklärung.
val numberOfFish = 50
val numberOfPlants = 23
if (numberOfFish > numberOfPlants) {
    println("Good ratio!") 
} else {
    println("Unhealthy ratio")
}
⇒ Good ratio!
  1. Verwenden Sie einen Bereich in einer if-Anweisung. In Kotlin können Sie für die zu testende Bedingung auch Bereiche verwenden.
val fish = 50
if (fish in 1..100) {
    println(fish)
}
⇒ 50
  1. Schreiben Sie eine if mit mehreren Fällen. Für kompliziertere Bedingungen verwenden Sie „und“ && und „oder“ ||. Wie in anderen Sprachen können Sie mit else if mehrere Fälle haben.
if (numberOfFish == 0) {
    println("Empty tank")
} else if (numberOfFish < 40) {
    println("Got fish!")
} else {
    println("That's a lot of fish!")
}
⇒ That's a lot of fish!
  1. Probieren Sie eine when-Anweisung aus. Es gibt eine bessere Möglichkeit, diese Reihe von if-/else if-/else-Anweisungen in Kotlin zu schreiben, nämlich mit der when-Anweisung, die der switch-Anweisung in anderen Sprachen entspricht. In Bedingungen in einer when-Anweisung können auch Bereiche verwendet werden.
when (numberOfFish) {
    0  -> println("Empty tank")
    in 1..39 -> println("Got fish!")
    else -> println("That's a lot of fish!")
}
⇒ That's a lot of fish!

In dieser Aufgabe erfahren Sie mehr über Variablen, die Nullwerte zulassen, und Variablen, die keine Nullwerte zulassen. Programmierfehler mit Nullwerten haben schon zu unzähligen Bugs geführt. Kotlin soll die Anzahl von Fehlern reduzieren, indem nicht nullable Variablen eingeführt werden.

Schritt 1: Informationen zur Nullable-Funktion

Variablen können standardmäßig nicht null sein.

  1. Deklarieren Sie ein Int und weisen Sie ihm null zu.
var rocks: Int = null
⇒ error: null can not be a value of a non-null type Int
  1. Verwenden Sie den Fragezeichenoperator ? nach dem Typ, um anzugeben, dass eine Variable null sein kann. Deklarieren Sie ein Int? und weisen Sie ihm null zu.
var marbles: Int? = null

Bei komplexen Datentypen wie einer Liste:

  • Sie können zulassen, dass die Elemente der Liste null sind.
  • Die Liste darf null sein, aber wenn sie nicht null ist, dürfen ihre Elemente nicht null sein.
  • Sie können sowohl die Liste als auch die Elemente als „null“ zulassen.

Listen und einige andere komplexe Datentypen werden in einer späteren Aufgabe behandelt.

Schritt 2: Informationen zum ? und ?: Operatoren

Mit dem Operator ? können Sie auf null testen und sich so das Schreiben vieler if-/else-Anweisungen ersparen.

  1. Schreiben Sie Code, um zu prüfen, ob die Variable fishFoodTreats nicht null ist. Verringern Sie dann den Wert dieser Variablen.
var fishFoodTreats = 6
if (fishFoodTreats != null) {
    fishFoodTreats = fishFoodTreats.dec()
}
  1. Sehen wir uns nun an, wie das in Kotlin mit dem ?-Operator geschrieben wird.
var fishFoodTreats = 6
fishFoodTreats = fishFoodTreats?.dec()
  1. Sie können auch Nulltests mit dem Operator ?: verketten. Sehen Sie sich dieses Beispiel an:
fishFoodTreats = fishFoodTreats?.dec() ?: 0

Es ist eine Kurzform für „Wenn fishFoodTreats nicht null ist, dekrementiere den Wert und verwende ihn. Andernfalls verwende den Wert nach dem ?:, also 0.“ Wenn fishFoodTreats null ist, wird die Auswertung beendet und die Methode dec() wird nicht aufgerufen.

Hinweis zu Nullzeigern

Wenn Sie NullPointerExceptions wirklich lieben, können Sie sie in Kotlin behalten. Der Not-Null-Assertionsoperator, !! (Double-Bang), konvertiert jeden Wert in einen Typ, der nicht null ist, und löst eine Ausnahme aus, wenn der Wert null ist.

val len = s!!.length   // throws NullPointerException if s is null

In dieser Aufgabe lernen Sie Arrays und Listen sowie verschiedene Möglichkeiten kennen, Schleifen in der Programmiersprache Kotlin zu erstellen.

Schritt 1: Listen erstellen

Listen sind ein grundlegender Typ in Kotlin und ähneln Listen in anderen Sprachen.

  1. Deklarieren Sie eine Liste mit listOf und geben Sie sie aus. Diese Liste kann nicht geändert werden.
val school = listOf("mackerel", "trout", "halibut")
println(school)
⇒ [mackerel, trout, halibut]
  1. Deklarieren Sie eine Liste, die mit mutableListOf geändert werden kann. Entfernen Sie ein Element.
val myList = mutableListOf("tuna", "salmon", "shark")
myList.remove("shark")
⇒ res36: kotlin.Boolean = true

Die Methode remove() gibt true zurück, wenn das übergebene Element erfolgreich entfernt wurde.

Schritt 2: Arrays erstellen

Wie andere Sprachen hat auch Kotlin Arrays. Im Gegensatz zu Listen in Kotlin, die mutable und immutable Versionen haben, gibt es keine mutable Version von Array. Nachdem Sie ein Array erstellt haben, ist die Größe festgelegt. Sie können keine Elemente hinzufügen oder entfernen, es sei denn, Sie kopieren sie in ein neues Array.

Die Regeln für die Verwendung von val und var sind bei Arrays und Listen gleich.

  1. Mit arrayOf ein Array von Strings deklarieren Verwenden Sie das Array-Dienstprogramm java.util.Arrays.toString(), um es auszugeben.
val school = arrayOf("shark", "salmon", "minnow")
println(java.util.Arrays.toString(school))
⇒ [shark, salmon, minnow]
  1. Ein mit arrayOf deklariertes Array hat keinen Typ, der den Elementen zugeordnet ist. Daher können Sie Typen mischen, was hilfreich sein kann. Ein Array mit verschiedenen Typen deklarieren
val mix = arrayOf("fish", 2)
  1. Sie können auch Arrays mit einem Typ für alle Elemente deklarieren. Deklarieren Sie ein Array von Ganzzahlen mit intArrayOf(). Es gibt entsprechende Builder oder Instanziierungsfunktionen für Arrays anderer Typen.
val numbers = intArrayOf(1,2,3)
  1. Kombinieren Sie zwei Arrays mit dem Operator +.
val numbers = intArrayOf(1,2,3)
val numbers3 = intArrayOf(4,5,6)
val foo2 = numbers3 + numbers
println(foo2[5])
=> 3
  1. Probieren Sie verschiedene Kombinationen aus verschachtelten Arrays und Listen aus. Wie in anderen Sprachen können Sie Arrays und Listen verschachteln. Wenn Sie ein Array in ein anderes einfügen, erhalten Sie also ein Array von Arrays und nicht ein zusammengeführtes Array mit den Inhalten der beiden Arrays. Die Elemente eines Arrays können auch Listen sein und die Elemente von Listen können Arrays sein.
val numbers = intArrayOf(1, 2, 3)
val oceans = listOf("Atlantic", "Pacific")
val oddList = listOf(numbers, oceans, "salmon")
println(oddList)
⇒ [[I@89178b4, [Atlantic, Pacific], salmon]

Das erste Element, numbers, ist ein Array. Wenn Sie das Array-Dienstprogramm nicht zum Ausgeben verwenden, gibt Kotlin die Adresse anstelle des Inhalts des Arrays aus.

  1. Eine praktische Funktion von Kotlin ist, dass Sie Arrays mit Code initialisieren können, anstatt sie auf 0 zu setzen. Beispiel:
val array = Array (5) { it * 2 }
println(java.util.Arrays.toString(array))
⇒ [0, 2, 4, 6, 8]

Der Initialisierungscode befindet sich zwischen den geschweiften Klammern, {}. Im Code bezieht sich it auf den Array-Index, beginnend mit 0.

Schritt 3: Loops erstellen

Nachdem Sie nun Listen und Arrays haben, funktioniert das Durchlaufen der Elemente wie erwartet.

  1. Array erstellen Verwenden Sie eine for-Schleife, um das Array zu durchlaufen und die Elemente auszugeben.
val school = arrayOf("shark", "salmon", "minnow")
for (element in school) {
    print(element + " ")
}
⇒ shark salmon minnow
  1. In Kotlin können Sie gleichzeitig die Elemente und die Indexe durchlaufen. Beispiel:
for ((index, element) in school.withIndex()) {
    println("Item at $index is $element\n")
}
⇒ Item at 0 is shark
Item at 1 is salmon
Item at 2 is minnow
  1. Probieren Sie verschiedene Schrittgrößen und ‑bereiche aus. Sie können Bereiche von Zahlen oder Zeichen alphabetisch angeben. Wie in anderen Sprachen müssen Sie nicht um 1 vorwärts gehen. Mit downTo können Sie einen Schritt zurückgehen.
for (i in 1..5) print(i)
⇒ 12345

for (i in 5 downTo 1) print(i)
⇒ 54321

for (i in 3..6 step 2) print(i)
⇒ 35

for (i in 'd'..'g') print (i)
⇒ defg
  1. Probieren Sie einige Loops aus. Wie andere Sprachen hat Kotlin while-Schleifen, do...while-Schleifen sowie ++- und ---Operatoren. In Kotlin gibt es auch repeat-Schleifen.
var bubbles = 0
while (bubbles < 50) {
    bubbles++
}
println("$bubbles bubbles in the water\n")

do {
    bubbles--
} while (bubbles > 50)
println("$bubbles bubbles in the water\n")

repeat(2) {
     println("A fish is swimming")
}
⇒ 50 bubbles in the water
49 bubbles in the water
A fish is swimmingA fish is swimming

Kotlin ähnelt anderen Sprachen in Bezug auf die Grundlagen wie Operatoren, Listen und Schleifen, es gibt jedoch einige wichtige Unterschiede.

Die folgenden Funktionen können sich in Kotlin von anderen Sprachen unterscheiden:

  • Kotlin-Typen können nicht implizit konvertiert werden. Verwenden Sie stattdessen die Typumwandlung.
  • Variablen, die mit val deklariert werden, kann nur einmal ein Wert zugewiesen werden.
  • Kotlin-Variablen sind standardmäßig nicht nullable. Verwenden Sie ?, um Variablen auf „nullable“ zu setzen.
  • Mit Kotlin können Sie in einer for-Schleife gleichzeitig den Index und die Elemente eines Arrays durchlaufen.

Die folgenden Kotlin-Programmierkonstrukte ähneln denen in anderen Sprachen:

  • Arrays und Listen können einen einzelnen Typ oder gemischte Typen haben.
  • Arrays und Listen können verschachtelt werden.
  • Sie können Schleifen mit for, while, do/while und repeat erstellen.
  • Die when-Anweisung ist die Kotlin-Version der switch-Anweisung, aber when ist flexibler.

Kotlin-Dokumentation

Wenn Sie weitere Informationen zu einem Thema in diesem Kurs benötigen oder nicht weiterkommen, ist https://kotlinlang.org der beste Ausgangspunkt.

Kotlin-Tutorials

Die Website https://try.kotlinlang.org enthält umfangreiche Tutorials namens „Kotlin Koans“, einen webbasierten Interpreter und eine vollständige Referenzdokumentation mit Beispielen.

Udacity-Kurs

Den Udacity-Kurs zu diesem Thema finden Sie unter Kotlin Bootcamp for Programmers.

IntelliJ IDEA

Dokumentation für IntelliJ IDEA finden Sie auf der JetBrains-Website.

In diesem Abschnitt werden mögliche Hausaufgaben für Schüler und Studenten aufgeführt, die dieses Codelab im Rahmen eines von einem Kursleiter geleiteten Kurses durcharbeiten. Es liegt in der Verantwortung des Kursleiters, Folgendes zu tun:

  • Weisen Sie bei Bedarf Aufgaben zu.
  • Teilen Sie den Schülern/Studenten mit, wie sie Hausaufgaben abgeben können.
  • Benoten Sie die Hausaufgaben.

Lehrkräfte können diese Vorschläge nach Belieben nutzen und auch andere Hausaufgaben zuweisen, die sie für angemessen halten.

Wenn Sie dieses Codelab selbst durcharbeiten, können Sie mit diesen Hausaufgaben Ihr Wissen testen.

Beantworten Sie diese Fragen

Frage 1

Welche der folgenden Optionen deklariert eine unveränderliche Liste von Strings?

▢ val school = arrayOf("shark", "salmon", "minnow")

▢ var school = arrayOf("shark", "salmon", "minnow")

▢ val school = listOf("shark", "salmon", "minnow")

▢ val school = mutableListOf("shark", "salmon", "minnow")

Frage 2

Was ist die Ausgabe des folgenden Codes?
for (i in 3..8 step 2) print(i)

▢ 345678

▢ 468

▢ 38

▢ 357

Frage 3

Was ist der Zweck des Fragezeichens in diesem Code?
var rocks: Int? = 3

▢ Der Typ der Variablen rocks ist nicht festgelegt.

▢ Die Variable rocks kann auf „null“ gesetzt werden.

▢ Die Variable rocks darf nicht auf „null“ gesetzt werden.

▢ Die Variable rocks sollte nicht sofort initialisiert werden.

Fahren Sie mit der nächsten Lektion fort: 3. Funktionen

Eine Übersicht über den Kurs mit Links zu anderen Codelabs finden Sie unter „Kotlin Bootcamp for Programmers: Welcome to the course“.