Kotlin logo

The Kotlin Blog

Kotlin Programming Language by JetBrains

Releases

Kotlin 1.5.0-RC veröffentlicht: Änderungen an Standard- und Testbibliothek

Kotlin 1.5.0-RC ist mit allen für 1.5.0 geplanten Features verfügbar – probieren Sie den gesamten Funktionsumfang der kommenden Version aus! Neue Sprachmerkmale, stdlib-Updates, eine verbesserte Testbibliothek und viele weitere Neuerungen erhalten nun den letzten Schliff. Bis zum endgültigen Release werden nur noch Fehlerkorrekturen vorgenommen.

Testen Sie mit 1.5.0-RC die modernen Kotlin-APIs in Ihren realen Projekten und helfen Sie uns mit Ihrem Feedback, die Release-Version zu verbessern! Sie können alle gefundenen Probleme in unserem YouTrack-Issue-Tracker melden.

1.5.0-RC installieren

In diesem Beitrag stellen wir Ihnen die Änderungen vor, die wir in 1.5.0-RC an der Kotlin-Standard- und Testbibliothek vorgenommen haben:

Lesen Sie weiter, um alle Details zu erfahren!

Stabile vorzeichenlose Ganzzahltypen

Die Standardbibliothek enthält eine API für vorzeichenlose Ganzzahlen, die für den Umgang mit nicht negativen Ganzzahlen sehr praktisch ist. Zu den Neuerungen zählen:

  • Vorzeichenlose Zahlentypen: UInt, ULong, UByte und UShort mit dazugehörigen Funktionen zum Beispiel für die Konvertierung.
  • Aggregattypen: Arrays, Bereiche und Progressionen von vorzeichenlosen Ganzzahlen: UIntArray, UIntRange und ähnliche Container für die anderen Typen.

Die Betaphase der vorzeichenlosen Ganzzahlen läuft seit Kotlin 1.3. Jetzt werden die vorzeichenlosen Ganzzahltypen und die dazugehörigen Operationen als stabil deklariert und ohne Opt-in bereitgestellt, und sie können ohne Weiteres in realen Projekten verwendet werden.

Die neuen stabilen APIs umfassen im Detail Folgendes:

  • Vorzeichenlose Ganzzahltypen
  • Bereiche und Progressionen von vorzeichenlosen Ganzzahltypen
  • Funktionen, die vorzeichenlose Ganzzahltypen verarbeiten

Die Arrays für vorzeichenlose Ganzzahlen verbleiben in der Betaphase. Dasselbe gilt für vorzeichenlose Ganzzahl-varargs, die auf Arrays basieren. Zu ihrer Verwendung ist ein Opt-in mithilfe der Annotation @ExperimentalUnsignedTypes erforderlich.

Erfahren Sie mehr über vorzeichenlose Ganzzahlen in Kotlin.

Erweiterungen für die java.nio.file.Path-API

Mit den Erweiterungsfunktionen für java.nio.file.Path bietet Kotlin jetzt die Möglichkeit, die moderne nicht-blockierende Java-IO-API in einem Kotlin-gemäßen Stil zu nutzen.

Ein kleines Beispiel:

Diese Erweiterungen wurden als experimentelles Feature in Kotlin 1.4.20 eingeführt und sind jetzt ohne Opt-in verfügbar. Sehen Sie sich die verfügbaren Funktionen im Paket kotlin.io.path an.

Die vorhandenen Erweiterungen für die File-API bleiben erhalten, sodass Sie Ihre bevorzugte API frei auswählen können.

Gebietsschema-agnostische API für Groß- und Kleinschreibung

Viele von Ihnen kennen die stdlib-Funktionen zum Ändern der Groß- und Kleinschreibung von Zeichenfolgen und Zeichen: toUpperCase(), toLowerCase(), toTitleCase(). Diese versehen in der Regel einwandfrei ihren Dienst. Schwierigkeiten entstehen nur beim Umgang mit verschiedenen Plattform-Gebietsschemas – alle Funktionen sind Gebietsschema-spezifisch, sodass sich die Ergebnisse je nach Gebietsschema unterscheiden können. Wie lautet zum Beispiel der Rückgabewert von "Kotlin".toUpperCase()? „Offensichtlich KOTLIN“, ist man versucht zu sagen. Nicht im türkischen Gebietsschema, wo das i groß geschrieben İ lautet. In dem Fall lautet das Ergebnis: KOTLİN.

Jetzt gibt es eine neue Gebietsschema-agnostische API zum Ändern der Groß- und Kleinschreibung von Zeichenfolgen und Zeichen: die Erweiterungen uppercase(), lowercase() und titlecase() sowie ihre *Char()-Pendants. Möglicherweise haben Sie bereits die Preview in 1.4.30 ausprobiert.

Die neuen Funktionen geben bei jedem Plattform-Gebietsschema identische Ergebnisse zurück. Rufen Sie einfach diese Funktionen auf und überlassen Sie den Rest der stdlib.

Die neuen Funktionen geben bei jedem Plattform-Gebietsschema identische Ergebnisse zurück. Rufen Sie einfach diese Funktionen auf und überlassen Sie den Rest der stdlib.

In der JVM können Sie eine Gebietsschema-spezifische Änderung der Groß- und Kleinschreibung vornehmen, indem Sie den neuen Funktionen das aktuelle Gebietsschema als Argument übergeben:

Die neuen Funktionen werden die alten Funktionen, die wir jetzt als veraltet gekennzeichnet haben, vollständig ersetzen.

Eindeutige Konvertierungen von Zeichen zu Code und Zeichen zu Zahl

Die Operation zum Abfragen des UTF-16-Codes eines Zeichens – die toInt()-Funktion – hat sich häufig als Stolperstein erwiesen, da sie bei Zeichenfolgen, die aus einer Ziffer bestehen, einer anderen Funktion sehr ähnlich sieht: String.toInt(), die aus der Ziffer eine Int produziert.

Darüber hinaus gab es keine gängige Funktion, die beim Char '4' den numerischen Wert 4 zurückgab.

Um diese Probleme zu lösen, gibt es jetzt neue Funktionen für die Konvertierung zwischen Zeichen und ihren Ganzzahlcodes bzw. numerischen Werten:

  • Char(code) und Char.code konvertieren zwischen einem Char und seinem Code.
  • Char.digitToInt(radix: Int) und deren *OrNull-Version produzieren eine Ganzzahl aus einer Ziffer im angegebenen Zahlensystem.
  • Int.digitToChar(radix: Int) erstellt aus einer Ziffer ein Zeichen, das die Ziffer im angegebenen Zahlensystem repräsentiert.

Diese Funktionen haben eindeutige Namen und machen den Code besser lesbar:

Die neuen Funktionen sind seit Kotlin 1.4.30 als Preview verfügbar und wurden jetzt als stabil markiert. Die alten Funktionen für die Konvertierung von Zeichen nach Zahlen (Char.toInt() und ähnliche Funktionen für andere numerische Typen) sowie von Zahlen nach Zeichen (Long.toChar() usw. mit der Ausnahme von Int.toChar()) wurden jetzt als veraltet gekennzeichnet.

Erweiterte Multiplattform-Zeichen-API

Wir arbeiten weiterhin an der Erweiterung des Multiplattform-Teils der Standardbibliothek, um alle Funktionen der Standardbibliothek für den gemeinsamen Code in Multiplattform-Projekten bereitzustellen.

Als neueste Entwicklung haben wir eine Reihe von Char-Funktionen für alle Plattformen und für gemeinsamen Code bereitgestellt. Diese Funktionen sind:

  • Char.isDigit(), Char.isLetter(), Char.isLetterOrDigit() – diese prüfen, ob ein Zeichen ein Buchstabe oder eine Ziffer ist.
  • Char.isLowerCase(), Char.isUpperCase(), Char.isTitleCase() – diese prüfen die Groß- bzw. Kleinschreibung eines Zeichens.
  • Char.isDefined() prüft, ob ein Zeichen einer allgemeinen Unicode-Kategorie – außer Cn (undefiniert) – zugeordnet ist.
  • Char.isISOControl() prüft, ob ein Zeichen ein ISO-Steuerzeichen ist, dessen Code in den Bereichen \u0000..\u001F oder \u007F..\u009F liegt.

Die Eigenschaft Char.category und ihr Rückgabetyp, die enum-Klasse CharCategory, die die allgemeine Unicode-Kategorie eines Zeichens angibt, sind jetzt in Multiplattform-Projekten verfügbar.

Strikte Versionen von String?.toBoolean()

Die String?.toBoolean()-Funktion von Kotlin wird häufig verwendet, um boolesche Werte aus Zeichenfolgen zu generieren. Die Funktionsweise ist ziemlich einfach: Bei der Zeichenfolge „true“ (unabhängig von Groß- und Kleinschreibung) wird true und bei allen anderen Zeichenfolgen – einschließlich null – wird false zurückgegeben.

Auch wenn dieses Verhalten selbstverständlich erscheint, können sich dahinter Fehlerzustände verbergen. Egal was wir mit dieser Funktion konvertieren, wir erhalten immer einen booleschen Wert – auch wenn die Zeichenfolge einen unerwarteten Wert hat.

Die neuen, strikten Versionen von String?.toBoolean() berücksichtigen die Groß- und Kleinschreibung und helfen Ihnen, solche Fehler zu vermeiden:

  • String.toBooleanStrict() löst für alle Eingaben mit Ausnahme der Literale „true“ und „false“ eine Ausnahme aus.
  • String.toBooleanStrictOrNull() gibt für alle Eingaben außer den Literalen „true“ und „false“ null zurück.

Änderungen an der Zeitmessungs-API

Die experimentelle API für Dauer- und Zeitmessungen ist seit Version 1.3.50 der stdlib verfügbar. Die API ermöglicht die präzise Messung von Zeitintervallen.

Eine der zentralen Klassen dieser API ist Duration. Sie repräsentiert die Zeitspanne zwischen zwei Zeitpunkten. In 1.5.0 wurden sowohl die API als die interne Darstellung von Duration erheblich geändert.

Duration verwendet jetzt Long statt Double für die interne Darstellung. Der Wertebereich von Long ermöglicht die Darstellung von mehr als einhundert Jahren mit der Genauigkeit einer Nanosekunde oder einhundert Millionen Jahren mit der Genauigkeit einer Millisekunde. Die zuvor unterstützten Zeitspannen im Sub-Nanosekunden-Bereich sind jedoch nicht mehr verfügbar.

Wir haben auch neue Eigenschaften zum Abrufen einer Duration als Long-Wert eingeführt. Diese sind für verschiedene Zeiteinheiten verfügbar: Duration.inWholeMinutes, Duration.inWholeSeconds usw. Diese Funktionen ersetzen die Double-basierten Eigenschaften wie Duration.inMinutes.

Eine weitere Änderung sind neue Factory-Funktionen zum Erstellen von Duration-Instanzen aus ganzzahligen Werten. Sie sind direkt im Duration-Typ definiert und ersetzen die alten Erweiterungseigenschaften von numerischen Typen wie z. B. Int.seconds.

Angesichts dieser umfangreichen Änderungen verbleibt die gesamte Zeitmessungs-API auch in 1.5.0 im experimentellen Status und erfordert ein Opt-in mit der Annotation @ExperimentalTime.

Bitte probieren Sie die neue Version aus und teilen Sie uns Ihr Feedback in unserem YouTrack-Issue-Tracker mit.

Mathematische Operationen: abgerundete Division und Mod-Operator

In Kotlin bewirkt der Divisionsoperator (/) bei Ganzzahlen eine abgeschnittene Division, bei der der nicht ganzzahlige Teil des Ergebnisses verworfen wird. In der modularen Arithmetik bietet die abgerundete Division eine Alternative hierzu. Dabei wird das Ergebnis abgerundet (in Richtung der kleineren Ganzzahl). Bei negativen Zahlen führt dies zu einem anderen Ergebnis.

Bisher erforderte die abgerundete Division eine benutzerdefinierte Funktion wie diese:

In 1.5.0-RC stellen wir die Funktion floorDiv() vor, die eine abgerundete Division von ganzen Zahlen ausführt.

In 1.5.0 führen wir die neue Funktion mod() ein. Diese funktioniert genau so, wie der Name erwarten lässt – sie gibt den Rest der abgerundeten Division zurück (Modulo).

Sie unterscheidet sich von rem() (oder dem %-Operator) in Kotlin. Der Modulo ist der Unterschied zwischen a und a.floorDiv(b) * b. Ein von null abweichender Modulo hat immer das gleiche Vorzeichen wie b, während a % b ein anderes Vorzeichen haben kann. Dies kann zum Beispiel bei der Implementierung von zyklischen Listen hilfreich sein:

Collections: firstNotNullOf() und firstNotNullOfOrNull()

Die Collections-API von Kotlin bietet eingebaute Funktionen für zahlreiche gängige Operationen mit Collections. Bei selteneren Einsatzfällen lassen sich normalerweise mehrere Aufrufe dieser Funktionen kombinieren. Dies funktioniert, sieht aber nicht immer elegant aus und kann Overhead verursachen.

Um beispielsweise das erste von null abweichende Ergebnis einer Auswahlfunktion für die Collection-Elemente zu erhalten, können wir mapNotNull() und first() verwenden. In 1.5.0 reicht dafür ein einziger Aufruf der neuen Funktion firstNotNullOf(). Zusammen mit firstNotNullOf() führen wir auch die *orNull()-Variante ein, die null zurückgibt, wenn kein Rückgabewert vorhanden ist.

Hier ist ein Beispiel, wie Sie damit Ihren Code verkürzen können.

Angenommen, Sie haben eine Klasse mit einer nullfähigen Eigenschaft, und Sie benötigen den ersten Nicht-Null-Wert aus einer Liste von Klasseninstanzen.

Sie können dies implementieren, indem Sie die Collection durchlaufen und prüfen, ob die Eigenschaft nicht null ist:

Eine andere Möglichkeit ist, die bestehenden Funktionen mapNotNull() und firstOrNull() zu verwenden. Zu beachten ist dabei, dass mapNotNull() eine temporäre Collection mit zusätzlichem Speicherbedarf erstellt, was insbesondere bei großen Collections ins Gewicht fällt. Daher kann hier auch eine Umwandlung in eine Sequenz erforderlich sein.

Und so sieht es bei Verwendung der neuen Funktion aus:

Änderungen in der Testbibliothek

In den letzten Releases haben wir keine größeren Updates an der Kotlin-Testbibliothek kotlin-test vorgenommen. Diesmal gibt es jedoch einige lang erwartete Änderungen. Mit 1.5.0-RC können Sie verschiedene neue Funktionen ausprobieren:

  • Eine einzige kotlin-test-Abhängigkeit in Multiplattform-Projekten.
  • Automatische Auswahl eines Testframeworks für Kotlin/JVM-Quellcode-Sets.
  • Aktualisierte Assertion-Funktionen.

Abhängigkeit von kotlin-test in Multiplattform-Projekten

Wir arbeiten weiter am Konfigurationsprozess für Multiplattform-Projekte. In 1.5.0 haben wir das Einrichten einer Abhängigkeit von kotlin-test für alle Quellcode-Sets vereinfacht.

Jetzt ist die kotlin-test-Abhängigkeit im gemeinsamen Test-Quellcode-Set die einzige Abhängigkeit, die Sie hinzufügen müssen. Das Gradle-Plugin leitet daraus die entsprechende plattformspezifische Abhängigkeit für die anderen Quellcode-Sets ab:

  • kotlin-test-junit für JVM-Quellcode-Sets. Sie können auch zu kotlin-test-junit-5 oder kotlin-test-testng wechseln, indem Sie diese explizit aktivieren (lesen Sie weiter, um zu erfahren, wie das geht).
  • kotlin-test-js für Kotlin/JS-Quellcode-Sets.
  • kotlin-test-common und kotlin-test-annotations-common für gemeinsame Quellcode-Sets.
  • Für Kotlin/Native-Quellcode-Sets ist kein zusätzliches Artefakt erforderlich, da Kotlin/Native integrierte Implementierungen der kotlin-test-API bereitstellt.

Automatische Auswahl eines Testframeworks für Kotlin/JVM-Quellcode-Sets

Sobald Sie wie oben beschrieben die Abhängigkeit des gemeinsamen Test-Quellcode-Sets von kotlin-test deklariert haben, werden die JVM-Quellcode-Sets automatisch um die Abhängigkeit von JUnit 4 ergänzt. Das war’s! Sie können sofort mit dem Schreiben und Ausführen von Tests loslegen!

So sieht es in der Groovy-DSL aus:

Und in der Kotlin-DSL:

Sie können auch zu JUnit 5 oder TestNG wechseln, indem Sie im Test-Task einfach eine Funktion aufrufen: useJUnitPlatform() bzw. useTestNG().

Dies funktioniert auch in Nur-JVM-Projekten, wenn Sie die Abhängigkeit von kotlin-test hinzufügen.

Aktualisierte Assertion-Funktionen

1.5.0 enthält eine Reihe neuer Assertion-Funktionen sowie Verbesserungen an bestehenden Funktionen.

Sehen wir uns zunächst die neuen Funktionen an:

  • assertIs<T>() und assertIsNot<T>() prüfen den Typ des Werts.
  • assertContentEquals() vergleicht den Inhalt von Containern wie Arrays, Sequenzen und beliebigen Iterable-Instanzen. Genauer gesagt wird geprüft, ob expected und actual die gleichen Elemente in der gleichen Reihenfolge enthalten.
  • assertEquals() und assertNotEquals() für Double und Float haben neue Überladungen mit einem dritten Parameter: Präzision.
  • assertContains() prüft das Vorhandensein eines Elements in einem Objekt, in dem der Operator contains() definiert ist: Array, Liste, Bereich usw.

Das folgende kurze Beispiel zeigt die Verwendung dieser Funktionen:

Und nun zu den bestehenden Assertion-Funktionen: Jetzt ist es möglich, Suspending-Funktionen im Inneren der Lambda-Funktion aufzurufen, die an assertTrue(), assertFalse() und expect() übergeben wird, da diese Funktionen jetzt inline sind.

Probieren Sie alle Features von Kotlin 1.5.0 aus

Nutzen Sie mit 1.5.0-RC all diese modernen Kotlin-APIs in Ihren realen Projekten!

Installieren Sie in IntelliJ IDEA oder Android Studio das Kotlin-Plugin 1.5.0-RC. Erfahren Sie, wie Sie EAP-Plugin-Versionen erhalten können.

Kompilieren Sie Ihre vorhandenen Projekte mit 1.5.0-RC, um zu überprüfen, wie sie mit 1.5.0 funktionieren. Dank der neuen, vereinfachten Konfiguration für Preview-Versionen müssen Sie nur die Kotlin-Version auf 1.5.0-RC ändern und bei Bedarf die Abhängigkeitsversionen anpassen.

1.5.0-RC installieren

Wie immer können Sie die neueste Version online auf dem Kotlin Playground ausprobieren.

Kompatibilität

Wie bei allen Feature-Releases werden mit Kotlin 1.5.0 einige Deprecation-Zyklen für zuvor angekündigte Änderungen abgeschlossen. Alle diese Fälle wurden vom Sprachkomitee sorgfältig geprüft und sind im Kompatibilitätsleitfaden für Kotlin 1.5 aufgeführt. Sie können diese Änderungen auch in YouTrack einsehen.

RC-Versionshinweise

Nachdem Kotlin 1.5.0 nun den Release-Candidate-Status erreicht hat, ist es Zeit für Sie, mit dem Kompilieren und Veröffentlichen zu beginnen! Im Gegensatz zu früheren Milestone-Releases sind mit Kotlin 1.5.0-RC erstellte Binärdateien garantiert mit Kotlin 1.5.0 kompatibel.

Geben Sie uns Feedback

Dies ist die letzte Gelegenheit für Sie, auf die nächste Feature-Version Einfluss zu nehmen! Teilen Sie uns alle Probleme im Issue-Tracker mit. Machen Sie Kotlin 1.5.0 besser – für sich selbst und die Community!

1.5.0-RC installieren

Discover more