Errata Kotlin (1. Aufl. 2020)

Diese Seite enthält Updates und Errata zum Buch »Kotlin« (1. Aufl. 2020).

S. 49 (Modulo-Operator)

Auf S. 49 hat sich ein fehlerhaftes Beispiel eingeschlichen, 20.1 & 6. Gemeint war 20.1 % 6, das Ergebnis ist 2,1.

S. 57 (Nullable)

Die letzte Zeile im Code am Ende der Seite lautet var d = a!!. Gemeint war aber var d = b!!. Da b den Zustand null hat, wird durch die erzwungene Auswertung von b ein Fehler ausgelöst.

S. 70 (Tabelle »Besondere Klassen und Objekte«)

In der ersten Zeile beziehe ich mich auf object in Java. Da Object (ein wenig verwirrend) eine Klasse ist, muss das Schlüsselwort groß geschrieben werden (also Object in Java).

S. 80/81 (Die Klasse Char)

In den Listings habe ich die Variable c zweimal in Java-Schreibweise mit char deklariert. Richtig ist in beiden Fällen var c='A'. Der Kotlin-Compiler wählt automatisch den richtigen Datentyp Char.

S. 126 (binarySearch)

Wenn binarySearch das Element nicht findet, liefert die Funktion eine negative Zahl zurück. Diese gibt den invertierten Einfügepunkt an, der sich als -insertPoint - 1 errechnet. (Der Einfügepunkt ist die Stelle, an der das gesuchte Element in die sortierte Liste eingefügt werden müsste.)

Um das nächst größere Element aus der Liste auszulesen, müssen Sie wie folgt vorgehen:

val sortedNumbers = List(100) { it * 7 }  // [0, 7, 14, ..., 693]
val pos = sortedNumbers.binarySearch(255)
if (pos>0)
    println("255 ist an der Position $pos in der Liste enthalten")
else {
    println("255 ist nicht enthalten. Die nächstgrößere Zahl")
    println("lautet ${sortedNumbers[-(pos+1)]}.")  // <-- KORREKTUR
}
// Ausgabe:  255 ist nicht enthalten. Die nächstgrößere Zahl
//           lautet 259.                              <-- KORREKTUR
S. 144 (magisches Quadrat)

Beim Spaltentest sind die Variablen in den beiden Schleifen vertauscht. Korrekt sieht der Code so aus:

// Spalten testen
for (col in 0 until n) {     // korrigiert, col statt row
    var sum = 0
    for (row in 0 until n)   // korrigiert row statt col
        sum += quad[row][col]
    if (sum != magicNr)
        return false
}
S. 145 (Mehrdimensionale Arrays)

Um ein dreidimensionales Array aus 10x10x10 Double-Zahlen zu erzeugen, gehen Sie so vor:

val dd = Array(10) { Array(10) { DoubleArray(10) } }
S. 155 (Kasten while versus do-while)

Im ersten Absatz des Kastens erkläre ich (korrekt) den Unterschied zwischen while und do-while, nur um die beiden Konstruktionen im zweiten Absatz zu vertauschen. Korrekt lautet der zweite Absatz des Kastens so:

Die beiden obigen Beispiele scheinen sich gleich zu verhalten. Wenn Sie aber als Startwert i = 200000 verwenden, dann wird die do-while-Schleife dennoch einmal durchlaufen (Ausgabe 400000), während die while-Schleife nicht ausgeführt wird.

S. 180 (Pfadsuche)

Im letzten Absatz habe ich MutableList<List<Char>> und List<MutableList<Char>> durcheinandergebracht. Richtig liest sich der Absatz so:

Vielleicht irritiert Sie, dass der Parameter von printMaze als List<List<Char>> deklariert ist, obwohl die ursprüngliche maze-Variable den Typ List<MutableList<Char>> hat. Das ist zulässig, weil die Liste innerhalb der Funktion nicht verändert wird und List<T> die Basisklasse für MutableList<T> ist. (Umgekehrt können Sie eine Liste mit dem Datentyp List<T> allerdings nicht an eine Funktion mit dem Parameter MutableList<T> übergeben.)

S. 185 (Code depth-search)

In der 9. Zeile des Codes muss es maze[start.row][start.col] = '.' heißen, d.h. im betroffenen Element muss ein Punkt, kein Leerzeichen gespeichert werden. (In den Beispieldateien zum Buch ist der Code korrekt.)

maze[start.row][start.col] = '.'  // Startpunkt als 
                           // ^      bearbeitet markieren
S. 267 (Enumerationen wie Klassen verwenden)

Damit der Code des Enumerationsbeispiels zur Fortsetzung auf S. 268 passt, muss in der zweite Zeile die Initialisierung von StateB korrigiert werden:

enum class FunnyEnum(val x: Int) : MyInterface {
    StateA(12), StateB(15), StateC(34);
    //                 ^^
    ...
S. 287 (Die component-Methoden)

Es handelt sich nicht um eine Destructing, sondern um eine Destructuring Declaration.

S. 329 (Reflexion)

Der einzige Supertyp von Person::class ist kotlin.Any.

val kc = Person::class    // kc hat den Typ KClass<Person>
...
println(kc.allSupertypes) // [class kotlin.Any]

Die im Buch irrtümlich angegebenen Supertypen beziehen sich auf die Employee-Klasse, also:

println(Employee::class.allSuperclasses)  // [class Person, class kotlin.Any, class TeamLeader]
S. 339 (Sternprojektion)

Beim Listing im Buch auf S. 339 mitte ist cnt++ nicht richtig eingerückt. Korrekt sieht das Listing so aus:

fun Iterable<*>.countNotNull(): Int {
    var cnt = 0
    for (itm in this)
        if (itm != null)
            cnt++            // <--
    return cnt
}
S. 350 (Type-safe Builder)

Das Listing, das am Seitenende beginnt, befindet sich in der Klasse Sample2 des Beispielprojekts type-safe (nicht in Sample1).

S. 366 (Eigene Exception-Klassen)

Das Listing am Seitenanfang sollte so aussehen:

class DbException(
    msg: String
    val connectionData: String? = null) : Exception(msg) 
S. 465 (Suchausdruck für select / LIKE)

Der LIKE-Platzhalter für ein beliebiges Zeichen ist _ (nicht ? wie im Buch angegeben).

S. 557 (Android Studio: Datei zu den Assets hinzufügen)

Auf S. 557 habe ich beklagt, dass es unmöglich ist, per Drag&Drop eine Datei zu den Assets hinzuzufügen. Es gibt aber einen alternativen Weg: Sie wählen die Datei im Dateimanager/Windows Explorer/Finder aus, kopieren Sie (Strg+C) und fügen Sie dann in Android Studio ein (Edit/Paste).

S. 606 (App-Permissions)

Für den Internetzugang ist nur android.permission.INTERNET erforderlich, nicht aber android.permission.ACCESS_NETWORK_STATE.

S. 700 (HTMLBuilder / buildString)

In buildString sollte statt appendln (deprecated) besser appendLine verwendet werden.

S. 758 (App-Permissions)

Für den Internetzugang ist nur android.permission.INTERNET erforderlich, nicht aber android.permission.ACCESS_NETWORK_STATE.


Letzte Änderung 15.2.2021. Vielen Dank an alle Leser, die mir Feedback geben (und ganz speziell an Herrn Abts, Herrn Krumbiegel und Herrn Zinn)!