{"id":137759,"date":"2021-04-22T09:09:26","date_gmt":"2021-04-22T08:09:26","guid":{"rendered":"https:\/\/blog.jetbrains.com\/?post_type=kotlin&#038;p=137759"},"modified":"2021-04-22T09:09:27","modified_gmt":"2021-04-22T08:09:27","slug":"kotlin-1-5-0-rc-veroeffentlicht-aenderungen-an-standard-und-testbibliothek","status":"publish","type":"kotlin","link":"https:\/\/blog.jetbrains.com\/de\/kotlin\/2021\/04\/kotlin-1-5-0-rc-veroeffentlicht-aenderungen-an-standard-und-testbibliothek\/","title":{"rendered":"Kotlin 1.5.0-RC ver\u00f6ffentlicht: \u00c4nderungen an Standard- und Testbibliothek"},"content":{"rendered":"<p>Kotlin 1.5.0-RC ist mit allen f\u00fcr 1.5.0 geplanten Features verf\u00fcgbar \u2013 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\u00fcltigen Release werden nur noch Fehlerkorrekturen vorgenommen.<\/p>\n<\/p>\n<p>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\u00f6nnen alle gefundenen Probleme in unserem <a href=\"https:\/\/kotl.in\/issue\" target=\"_blank\" rel=\"noopener\">YouTrack<\/a>-Issue-Tracker melden.<\/p>\n<p align=\"center\"><a class=\"jb-download-button\" title=\"Installieren\" href=\"https:\/\/kotlinlang.org\/docs\/install-eap-plugin.html\" target=\"_blank\" rel=\"noopener\">1.5.0-RC installieren<\/a><\/p>\n<p>In diesem Beitrag stellen wir Ihnen die \u00c4nderungen vor, die wir in 1.5.0-RC an der Kotlin-Standard- und Testbibliothek vorgenommen haben:<\/p>\n<ul>\n<li><a href=\"https:\/\/blog.jetbrains.com\/kotlin\/2021\/04\/kotlin-1-5-0-rc-released\/#stable-unsigned-integer-types\">Stabile vorzeichenlose Ganzzahltypen<\/a><\/li>\n<li><a href=\"https:\/\/blog.jetbrains.com\/kotlin\/2021\/04\/kotlin-1-5-0-rc-released\/#extensions-for-java-nio-path\">Erweiterungen f\u00fcr java.nio.file.Path<\/a><\/li>\n<li><a href=\"https:\/\/blog.jetbrains.com\/kotlin\/2021\/04\/kotlin-1-5-0-rc-released\/#locale-agnostic-upper-lowercase\">Verbesserungen an der String- und Char-API<\/a><\/li>\n<li><a href=\"https:\/\/blog.jetbrains.com\/kotlin\/2021\/04\/kotlin-1-5-0-rc-released\/#duration-api-changes\">\u00c4nderungen an der Zeitmessungs-API<\/a><\/li>\n<li><a href=\"https:\/\/blog.jetbrains.com\/kotlin\/2021\/04\/kotlin-1-5-0-rc-released\/#math-operations-floordiv-mod\">Neue mathematische Operationen f\u00fcr modulare Arithmetik<\/a><\/li>\n<li><a href=\"https:\/\/blog.jetbrains.com\/kotlin\/2021\/04\/kotlin-1-5-0-rc-released\/#collections-firstnotnullof\">Neue Collection-Funktionen<\/a><\/li>\n<li><a href=\"https:\/\/blog.jetbrains.com\/kotlin\/2021\/04\/kotlin-1-5-0-rc-released\/#test-library-changes\">\u00c4nderungen in der Testbibliothek<\/a><\/li>\n<\/ul>\n<p>Lesen Sie weiter, um alle Details zu erfahren!<\/p>\n<p><a name = \"stable-unsigned-integer-types\"><\/a><\/p>\n<h2>Stabile vorzeichenlose Ganzzahltypen<\/h2>\n<p>Die Standardbibliothek enth\u00e4lt eine API f\u00fcr vorzeichenlose Ganzzahlen, die f\u00fcr den Umgang mit nicht negativen Ganzzahlen sehr praktisch ist. Zu den Neuerungen z\u00e4hlen:<\/p>\n<ul>\n<li>Vorzeichenlose Zahlentypen: <code>UInt<\/code>, <code>ULong<\/code>, <code>UByte<\/code> und <code>UShort<\/code> mit dazugeh\u00f6rigen Funktionen zum Beispiel f\u00fcr die Konvertierung.<\/li>\n<li>Aggregattypen: Arrays, Bereiche und Progressionen von vorzeichenlosen Ganzzahlen: <code>UIntArray<\/code>, <code>UIntRange<\/code> und \u00e4hnliche Container f\u00fcr die anderen Typen.<\/li>\n<\/ul>\n<p>Die Betaphase der vorzeichenlosen Ganzzahlen l\u00e4uft seit <a href=\"https:\/\/kotlinlang.org\/docs\/whatsnew13.html#unsigned-integers\" target=\"_blank\" rel=\"noopener\">Kotlin 1.3<\/a>. Jetzt werden die vorzeichenlosen Ganzzahltypen und die dazugeh\u00f6rigen Operationen als stabil deklariert und ohne Opt-in bereitgestellt, und sie k\u00f6nnen ohne Weiteres in realen Projekten verwendet werden.<\/p>\n<p>Die neuen stabilen APIs umfassen im Detail Folgendes:<\/p>\n<ul>\n<li>Vorzeichenlose Ganzzahltypen<\/li>\n<li>Bereiche und Progressionen von vorzeichenlosen Ganzzahltypen<\/li>\n<li>Funktionen, die vorzeichenlose Ganzzahltypen verarbeiten<\/li>\n<\/ul>\n<pre class=\"kotlin-code\" data-version=\"1.5.0-RC\" theme=\"idea\" indent=\"4\" style=\"visibility: hidden; padding: 36px 0;\">\nfun main() {\n\/\/sampleStart\n    val zero = 0U \/\/ Define unsigned numbers with literal suffixes\n    val ten = 10.toUInt() \/\/ or by converting non-negative signed numbers\n    \/\/val minusOne: UInt = -1U \/\/ Error: unary minus is not defined\n    val range: UIntRange = zero..ten \/\/ Separate types for ranges and progressions\n\n    for (i in range) print(i)\n    println()\n    println(&quot;UInt covers the range from ${UInt.MIN_VALUE} to ${UInt.MAX_VALUE}&quot;) \/\/ UInt covers the range from 0 to 4294967295\n\/\/sampleEnd\n}\n<\/pre>\n<p>Die Arrays f\u00fcr vorzeichenlose Ganzzahlen verbleiben in der Betaphase. Dasselbe gilt f\u00fcr vorzeichenlose Ganzzahl-<a href=\"https:\/\/kotlinlang.org\/docs\/functions.html#variable-number-of-arguments-varargs\" target=\"_blank\" rel=\"noopener\">varargs<\/a>, die auf Arrays basieren. Zu ihrer Verwendung ist ein Opt-in mithilfe der Annotation <code>@ExperimentalUnsignedTypes<\/code> erforderlich.<\/p>\n<p>Erfahren Sie mehr \u00fcber <a href=\"https:\/\/kotlinlang.org\/docs\/basic-types.html#unsigned-integers\" target=\"_blank\" rel=\"noopener\">vorzeichenlose Ganzzahlen in Kotlin<\/a>.<\/p>\n<p><a name = \"extensions-for-java-nio-path\"><\/a><\/p>\n<h2>Erweiterungen f\u00fcr die java.nio.file.Path-API<\/h2>\n<p>Mit den Erweiterungsfunktionen f\u00fcr <a href=\"https:\/\/docs.oracle.com\/javase\/7\/docs\/api\/java\/nio\/file\/Path.html\" target=\"_blank\" rel=\"noopener\"><code>java.nio.file.Path<\/code><\/a> bietet Kotlin jetzt die M\u00f6glichkeit, die moderne <a href=\"https:\/\/docs.oracle.com\/javase\/8\/docs\/api\/java\/nio\/package-summary.html\" target=\"_blank\" rel=\"noopener\">nicht-blockierende Java-IO-API<\/a> in einem Kotlin-gem\u00e4\u00dfen Stil zu nutzen.<\/p>\n<p>Ein kleines Beispiel:<\/p>\n<pre class=\"kotlin-code\" data-highlight-only=\"true\" theme=\"idea\" indent=\"4\" style=\"visibility: hidden; padding: 36px 0;\">\nimport kotlin.io.path.*\nimport java.nio.file.Path\n\nfun main() {\n    \/\/ construct path with the div (\/) operator\n    val baseDir = Path(&quot;\/base&quot;)\n    val subDir = baseDir \/ &quot;subdirectory&quot;\n\n    \/\/ list files in a directory\n    val kotlinFiles = Path(&quot;\/home\/user&quot;).listDirectoryEntries(&quot;*.kt&quot;)\n    \/\/ count lines in all kotlin files\n    val totalLines = kotlinFiles.sumOf { file -&gt; file.useLines { lines -&gt; lines.count() } }\n}\n<\/pre>\n<p>Diese Erweiterungen wurden als experimentelles Feature <a href=\"https:\/\/kotlinlang.org\/docs\/whatsnew1420.html#extensions-for-java-nio-file-path\" target=\"_blank\" rel=\"noopener\">in Kotlin 1.4.20<\/a> eingef\u00fchrt und sind jetzt ohne Opt-in verf\u00fcgbar. Sehen Sie sich die verf\u00fcgbaren Funktionen im Paket <a href=\"https:\/\/kotlinlang.org\/api\/latest\/jvm\/stdlib\/kotlin.io.path\/\" target=\"_blank\" rel=\"noopener\"><code>kotlin.io.path<\/code><\/a> an.<\/p>\n<p>Die vorhandenen Erweiterungen f\u00fcr die File-API bleiben erhalten, sodass Sie Ihre bevorzugte API frei ausw\u00e4hlen k\u00f6nnen.<\/p>\n<p><a name = \"locale-agnostic-upper-lowercase\"><\/a><\/p>\n<h2>Gebietsschema-agnostische API f\u00fcr Gro\u00df- und Kleinschreibung<\/h2>\n<p>Viele von Ihnen kennen die stdlib-Funktionen zum \u00c4ndern der Gro\u00df- und Kleinschreibung von Zeichenfolgen und Zeichen: <code>toUpperCase()<\/code>, <code>toLowerCase()<\/code>, <code>toTitleCase()<\/code>. Diese versehen in der Regel einwandfrei ihren Dienst. Schwierigkeiten entstehen nur beim Umgang mit verschiedenen Plattform-Gebietsschemas \u2013 alle Funktionen sind Gebietsschema-spezifisch, sodass sich die Ergebnisse je nach Gebietsschema unterscheiden k\u00f6nnen. Wie lautet zum Beispiel der R\u00fcckgabewert von <code>\"Kotlin\".toUpperCase()<\/code>? \u201eOffensichtlich <code>KOTLIN<\/code>\u201c, ist man versucht zu sagen. Nicht im t\u00fcrkischen Gebietsschema, wo das <code>i<\/code> gro\u00df geschrieben <code>\u0130<\/code> lautet. In dem Fall lautet das Ergebnis: <code>KOTL\u0130N<\/code>.<\/p>\n<p>Jetzt gibt es eine neue Gebietsschema-agnostische API zum \u00c4ndern der Gro\u00df- und Kleinschreibung von Zeichenfolgen und Zeichen: die Erweiterungen <code>uppercase()<\/code>, <code>lowercase()<\/code> und <code>titlecase()<\/code> sowie ihre <code>*Char()<\/code>-Pendants. M\u00f6glicherweise haben Sie bereits die <a href=\"https:\/\/kotlinlang.org\/docs\/whatsnew1430.html#locale-agnostic-api-for-upper-lowercasing-text\" target=\"_blank\" rel=\"noopener\">Preview in 1.4.30<\/a> ausprobiert.<\/p>\n<p>Die neuen Funktionen geben bei jedem Plattform-Gebietsschema identische Ergebnisse zur\u00fcck. Rufen Sie einfach diese Funktionen auf und \u00fcberlassen Sie den Rest der stdlib.<\/p>\n<p>Die neuen Funktionen geben bei jedem Plattform-Gebietsschema identische Ergebnisse zur\u00fcck. Rufen Sie einfach diese Funktionen auf und \u00fcberlassen Sie den Rest der stdlib.<\/p>\n<pre class=\"kotlin-code\" data-version=\"1.5.0-RC\" theme=\"idea\" indent=\"4\" style=\"visibility: hidden; padding: 36px 0;\">\nfun main() {\n\/\/sampleStart\n    \/\/ replace the old API\n    println(&quot;Kotlin&quot;.toUpperCase()) \/\/ KOTLIN or KOTL\u0130N or?..\n\n    \/\/ with the new API\n    println(&quot;Kotlin&quot;.uppercase()) \/\/ Always KOTLIN\n\/\/sampleEnd\n}\n<\/pre>\n<p>In der JVM k\u00f6nnen Sie eine Gebietsschema-spezifische \u00c4nderung der Gro\u00df- und Kleinschreibung vornehmen, indem Sie den neuen Funktionen das aktuelle Gebietsschema als Argument \u00fcbergeben:<\/p>\n<pre class=\"kotlin-code\" data-highlight-only=\"true\" theme=\"idea\" indent=\"4\" style=\"visibility: hidden; padding: 36px 0;\">\n&quot;Kotlin&quot;.uppercase(Locale.getDefault()) \/\/ Locale-sensitive uppercasing\n<\/pre>\n<p>Die neuen Funktionen werden die alten Funktionen, die wir jetzt als veraltet gekennzeichnet haben, vollst\u00e4ndig ersetzen.<\/p>\n<h2>Eindeutige Konvertierungen von Zeichen zu Code und Zeichen zu Zahl<\/h2>\n<p>Die Operation zum Abfragen des UTF-16-Codes eines Zeichens \u2013 die <code>toInt()<\/code>-Funktion \u2013 hat sich h\u00e4ufig als Stolperstein erwiesen, da sie bei Zeichenfolgen, die aus einer Ziffer bestehen, einer anderen Funktion sehr \u00e4hnlich sieht: <code>String.toInt()<\/code>, die aus der Ziffer eine <code>Int<\/code> produziert.<\/p>\n<pre class=\"kotlin-code\" data-highlight-only=\"true\" theme=\"idea\" indent=\"4\" style=\"visibility: hidden; padding: 36px 0;\">\n&quot;4&quot;.toInt() \/\/ returns 4\n'4'.toInt() \/\/ returns 52\n<\/pre>\n<p>Dar\u00fcber hinaus gab es keine g\u00e4ngige Funktion, die beim <code>Char<\/code> <code>'4'<\/code> den numerischen Wert <code>4<\/code> zur\u00fcckgab.<\/p>\n<p>Um diese Probleme zu l\u00f6sen, gibt es jetzt neue Funktionen f\u00fcr die Konvertierung zwischen Zeichen und ihren Ganzzahlcodes bzw. numerischen Werten:<\/p>\n<ul>\n<li><code>Char(code)<\/code> und <code>Char.code<\/code> konvertieren zwischen einem Char und seinem Code.<\/li>\n<li><code>Char.digitToInt(radix: Int)<\/code> und deren <code>*OrNull<\/code>-Version produzieren eine Ganzzahl aus einer Ziffer im angegebenen Zahlensystem.<\/li>\n<li><code>Int.digitToChar(radix: Int)<\/code> erstellt aus einer Ziffer ein Zeichen, das die Ziffer im angegebenen Zahlensystem repr\u00e4sentiert.<\/li>\n<\/ul>\n<p>Diese Funktionen haben eindeutige Namen und machen den Code besser lesbar:<\/p>\n<pre class=\"kotlin-code\" data-version=\"1.5.0-RC\" theme=\"idea\" indent=\"4\" style=\"visibility: hidden; padding: 36px 0;\">\nfun main() {\n\/\/sampleStart\n    val capsK = Char(75) \/\/ \u2018K\u2019\n    val one = '1'.digitToInt(10) \/\/ 1\n    val digitC = 12.digitToChar(16) \/\/ hexadecimal digit \u2018C\u2019\n\n    println(&quot;${capsK}otlin ${one}.5.0-R${digitC}&quot;) \/\/ \u201cKotlin 1.5.0-RC\u201d\n    println(capsK.code) \/\/ 75\n\/\/sampleEnd\n}\n<\/pre>\n<p>Die neuen Funktionen sind <a href=\"https:\/\/kotlinlang.org\/docs\/whatsnew1430.html#clear-char-to-code-and-char-to-digit-conversions\" target=\"_blank\" rel=\"noopener\">seit Kotlin 1.4.30<\/a> als Preview verf\u00fcgbar und wurden jetzt als stabil markiert. Die alten Funktionen f\u00fcr die Konvertierung von Zeichen nach Zahlen (<code>Char.toInt()<\/code> und \u00e4hnliche Funktionen f\u00fcr andere numerische Typen) sowie von Zahlen nach Zeichen (<code>Long.toChar()<\/code> usw. mit der Ausnahme von <code>Int.toChar()<\/code>) wurden jetzt als veraltet gekennzeichnet.<\/p>\n<h2>Erweiterte Multiplattform-Zeichen-API<\/h2>\n<p>Wir arbeiten weiterhin an der Erweiterung des Multiplattform-Teils der Standardbibliothek, um alle Funktionen der Standardbibliothek f\u00fcr den gemeinsamen Code in Multiplattform-Projekten bereitzustellen.<\/p>\n<p>Als neueste Entwicklung haben wir eine Reihe von <code>Char<\/code>-Funktionen f\u00fcr alle Plattformen und f\u00fcr gemeinsamen Code bereitgestellt. Diese Funktionen sind:<\/p>\n<ul>\n<li><code>Char.isDigit()<\/code>, <code>Char.isLetter()<\/code>, <code>Char.isLetterOrDigit()<\/code> \u2013 diese pr\u00fcfen, ob ein Zeichen ein Buchstabe oder eine Ziffer ist.<\/li>\n<li><code>Char.isLowerCase()<\/code>, <code>Char.isUpperCase()<\/code>, <code>Char.isTitleCase()<\/code> \u2013 diese pr\u00fcfen die Gro\u00df- bzw. Kleinschreibung eines Zeichens.<\/li>\n<li><code>Char.isDefined()<\/code> pr\u00fcft, ob ein Zeichen einer <a href=\"https:\/\/unicode.org\/reports\/tr44\/#General_Category_Values\" target=\"_blank\" rel=\"noopener\">allgemeinen Unicode-Kategorie<\/a> \u2013 au\u00dfer <code>Cn<\/code> (<em>undefiniert<\/em>) \u2013 zugeordnet ist.<\/li>\n<li><code>Char.isISOControl()<\/code> pr\u00fcft, ob ein Zeichen ein <a href=\"https:\/\/en.wikipedia.org\/wiki\/Control_character\" target=\"_blank\" rel=\"noopener\">ISO-Steuerzeichen<\/a> ist, dessen Code in den Bereichen <code>\\u0000<\/code>..<code>\\u001F<\/code> oder <code>\\u007F<\/code>..<code>\\u009F<\/code> liegt.<\/li>\n<\/ul>\n<p>Die Eigenschaft <code>Char.category<\/code> und ihr R\u00fcckgabetyp, die enum-Klasse <code>CharCategory<\/code>, die die allgemeine Unicode-Kategorie eines Zeichens angibt, sind jetzt in Multiplattform-Projekten verf\u00fcgbar.<\/p>\n<pre class=\"kotlin-code\" data-version=\"1.5.0-RC\" theme=\"idea\" indent=\"4\" style=\"visibility: hidden; padding: 36px 0;\">\nfun main() {\n\/\/sampleStart\n    val array = &quot;Kotlin 1.5.0-RC&quot;.toCharArray()\n    val (letterOrDigit, punctuation) = array.partition { it.isLetterOrDigit() }\n    val (upperCase, notUpperCase ) = array.partition { it.isUpperCase() }\n\n    println(&quot;$letterOrDigit, $punctuation&quot;) \/\/ [K, o, t, l, i, n, 1, 5, 0, R, C], [ , ., ., -]\n    println(&quot;$upperCase, $notUpperCase&quot;) \/\/ [K, R, C], [o, t, l, i, n, , 1, ., 5, ., 0, -]\n\n    if (array[0].isDefined()) println(array[0].category)\n\/\/sampleEnd\n}\n<\/pre>\n<h2>Strikte Versionen von String?.toBoolean()<\/h2>\n<p>Die <code>String?.toBoolean()<\/code>-Funktion von Kotlin wird h\u00e4ufig verwendet, um boolesche Werte aus Zeichenfolgen zu generieren. Die Funktionsweise ist ziemlich einfach: Bei der Zeichenfolge \u201etrue\u201c (unabh\u00e4ngig von Gro\u00df- und Kleinschreibung) wird <code>true<\/code> und bei allen anderen Zeichenfolgen \u2013 einschlie\u00dflich <code>null<\/code> \u2013 wird <code>false<\/code> zur\u00fcckgegeben.<\/p>\n<p>Auch wenn dieses Verhalten selbstverst\u00e4ndlich erscheint, k\u00f6nnen sich dahinter Fehlerzust\u00e4nde verbergen. Egal was wir mit dieser Funktion konvertieren, wir erhalten immer einen booleschen Wert \u2013 auch wenn die Zeichenfolge einen unerwarteten Wert hat.<\/p>\n<p>Die neuen, strikten Versionen von <a href=\"https:\/\/kotlinlang.org\/api\/latest\/jvm\/stdlib\/kotlin.text\/to-boolean.html\" target=\"_blank\" rel=\"noopener\">String?.toBoolean()<\/a> ber\u00fccksichtigen die Gro\u00df- und Kleinschreibung und helfen Ihnen, solche Fehler zu vermeiden:<\/p>\n<ul>\n<li><code>String.toBooleanStrict()<\/code> l\u00f6st f\u00fcr alle Eingaben mit Ausnahme der Literale \u201etrue\u201c und \u201efalse\u201c eine Ausnahme aus.<\/li>\n<li><code>String.toBooleanStrictOrNull()<\/code> gibt f\u00fcr alle Eingaben au\u00dfer den Literalen \u201etrue\u201c und \u201efalse\u201c null zur\u00fcck.<\/li>\n<\/ul>\n<pre class=\"kotlin-code\" data-version=\"1.5.0-RC\" theme=\"idea\" indent=\"4\" style=\"visibility: hidden; padding: 36px 0;\">\nfun main() {\n\/\/sampleStart\n    println(&quot;true&quot;.toBooleanStrict()) \/\/ True\n    \/\/ println(&quot;1&quot;.toBooleanStrict()) \/\/ Exception\n    println(&quot;1&quot;.toBooleanStrictOrNull()) \/\/ null\n    println(&quot;True&quot;.toBooleanStrictOrNull()) \/\/ null: the function is case-sensitive\n\/\/sampleEnd\n}\n<\/pre>\n<p><a name = \"duration-api-changes\"><\/a><\/p>\n<h2>\u00c4nderungen an der Zeitmessungs-API<\/h2>\n<p>Die experimentelle <a href=\"https:\/\/blog.jetbrains.com\/kotlin\/2019\/08\/kotlin-1-3-50-released\/#time-measurement-api\">API f\u00fcr Dauer- und Zeitmessungen<\/a> ist seit Version 1.3.50 der stdlib verf\u00fcgbar. Die API erm\u00f6glicht die pr\u00e4zise Messung von Zeitintervallen.<\/p>\n<p>Eine der zentralen Klassen dieser API ist <a href=\"https:\/\/kotlinlang.org\/api\/latest\/jvm\/stdlib\/kotlin.time\/-duration\/\" target=\"_blank\" rel=\"noopener\"><code>Duration<\/code><\/a>. Sie repr\u00e4sentiert die Zeitspanne zwischen zwei Zeitpunkten. In 1.5.0 wurden sowohl die API als die interne Darstellung von <code>Duration<\/code> erheblich ge\u00e4ndert.<\/p>\n<p><code>Duration<\/code> verwendet jetzt <code>Long<\/code> statt <code>Double<\/code> f\u00fcr die interne Darstellung. Der Wertebereich von <code>Long<\/code> erm\u00f6glicht die Darstellung von mehr als einhundert Jahren mit der Genauigkeit einer Nanosekunde oder einhundert Millionen Jahren mit der Genauigkeit einer Millisekunde. Die zuvor unterst\u00fctzten Zeitspannen im Sub-Nanosekunden-Bereich sind jedoch nicht mehr verf\u00fcgbar.<\/p>\n<p>Wir haben auch neue Eigenschaften zum Abrufen einer Duration als <code>Long<\/code>-Wert eingef\u00fchrt. Diese sind f\u00fcr verschiedene Zeiteinheiten verf\u00fcgbar: <code>Duration.inWholeMinutes<\/code>, <code>Duration.inWholeSeconds<\/code> usw. Diese Funktionen ersetzen die <code>Double<\/code>-basierten Eigenschaften wie <code>Duration.inMinutes<\/code>.<\/p>\n<p>Eine weitere \u00c4nderung sind neue Factory-Funktionen zum Erstellen von <code>Duration<\/code>-Instanzen aus ganzzahligen Werten. Sie sind direkt im <code>Duration<\/code>-Typ definiert und ersetzen die alten Erweiterungseigenschaften von numerischen Typen wie z.\u00a0B. <code>Int.seconds<\/code>.<\/p>\n<pre class=\"kotlin-code\" data-version=\"1.5.0-RC\" theme=\"idea\" indent=\"4\" style=\"visibility: hidden; padding: 36px 0;\">\nimport kotlin.time.ExperimentalTime\nimport kotlin.time.Duration\n\n@ExperimentalTime\nfun main() {\n    val duration = Duration.milliseconds(120000)\n    println(&quot;There are ${duration.inWholeSeconds} seconds in ${duration.inWholeMinutes} minutes&quot;)\n}\n<\/pre>\n<p>Angesichts dieser umfangreichen \u00c4nderungen verbleibt die gesamte Zeitmessungs-API auch in 1.5.0 im experimentellen Status und erfordert ein Opt-in mit der Annotation <code>@ExperimentalTime<\/code>.<\/p>\n<p>Bitte probieren Sie die neue Version aus und teilen Sie uns Ihr Feedback in unserem <a href=\"https:\/\/kotl.in\/issue\" target=\"_blank\" rel=\"noopener\">YouTrack<\/a>-Issue-Tracker mit.<\/p>\n<p><a name = \"math-operations-floordiv-mod\"><\/a><\/p>\n<h2>Mathematische Operationen: abgerundete Division und Mod-Operator<\/h2>\n<p>In Kotlin bewirkt der <a href=\"https:\/\/kotlinlang.org\/docs\/basic-types.html#operations\" target=\"_blank\" rel=\"noopener\">Divisionsoperator (<code>\/<\/code>) bei Ganzzahlen<\/a> eine <em>abgeschnittene Division<\/em>, bei der der nicht ganzzahlige Teil des Ergebnisses verworfen wird. In der modularen Arithmetik bietet die <em>abgerundete Division<\/em> eine Alternative hierzu. Dabei wird das Ergebnis abgerundet (in Richtung der kleineren Ganzzahl). Bei negativen Zahlen f\u00fchrt dies zu einem anderen Ergebnis.<\/p>\n<p>Bisher erforderte die abgerundete Division eine benutzerdefinierte Funktion wie diese:<\/p>\n<pre class=\"kotlin-code\" data-highlight-only=\"true\" theme=\"idea\" indent=\"4\" style=\"visibility: hidden; padding: 36px 0;\">\nfun floorDivision(i: Int, j: Int): Int {\n    var result = i \/ j\n    if (i != 0 &amp;&amp; result &lt;= 0) result--\n    return result\n}\n<\/pre>\n<p>In 1.5.0-RC stellen wir die Funktion <code>floorDiv()<\/code> vor, die eine abgerundete Division von ganzen Zahlen ausf\u00fchrt.<\/p>\n<pre class=\"kotlin-code\" data-version=\"1.5.0-RC\" theme=\"idea\" indent=\"4\" style=\"visibility: hidden; padding: 36px 0;\">\nfun main() {\n\/\/sampleStart\n    println(&quot;Truncated division -5\/3: ${-5 \/ 3}&quot;)\n    println(&quot;Floored division -5\/3: ${(-5).floorDiv(3)}&quot;)\n\/\/sampleEnd\n}\n<\/pre>\n<p>In 1.5.0 f\u00fchren wir die neue Funktion <code>mod()<\/code> ein. Diese funktioniert genau so, wie der Name erwarten l\u00e4sst \u2013 sie gibt den Rest der abgerundeten Division zur\u00fcck (<em>Modulo<\/em>).<\/p>\n<p>Sie unterscheidet sich von <code>rem()<\/code> (oder dem <code>%<\/code>-Operator) in Kotlin. Der Modulo ist der Unterschied zwischen <code>a<\/code> und <code>a.floorDiv(b) * b<\/code>. Ein von null abweichender Modulo hat immer das gleiche Vorzeichen wie <code>b<\/code>, w\u00e4hrend <code>a % b<\/code> ein anderes Vorzeichen haben kann. Dies kann zum Beispiel bei der Implementierung von zyklischen Listen hilfreich sein:<\/p>\n<pre class=\"kotlin-code\" data-version=\"1.5.0-RC\" theme=\"idea\" indent=\"4\" style=\"visibility: hidden; padding: 36px 0;\">\nfun main() {\n\/\/sampleStart\n    fun getNextIndexCyclic(current: Int, size: Int ) = (current + 1).mod(size)\n    fun getPreviousIndexCyclic(current: Int, size: Int ) = (current - 1).mod(size)\n    \/\/ unlike %, mod() produces the expected non-negative value even if (current - 1) is less than 0\n\n    val size = 5\n    for (i in 0..(size * 2)) print(getNextIndexCyclic(i, size))\n    println()\n    for (i in 0..(size * 2)) print(getPreviousIndexCyclic(i, size))\n\/\/sampleEnd\n}\n<\/pre>\n<p><a name = \"collections-firstnotnullof\"><\/a><\/p>\n<h2>Collections: firstNotNullOf() und firstNotNullOfOrNull()<\/h2>\n<p>Die Collections-API von Kotlin bietet eingebaute Funktionen f\u00fcr zahlreiche g\u00e4ngige Operationen mit Collections. Bei selteneren Einsatzf\u00e4llen lassen sich normalerweise mehrere Aufrufe dieser Funktionen kombinieren. Dies funktioniert, sieht aber nicht immer elegant aus und kann Overhead verursachen.<\/p>\n<p>Um beispielsweise das erste von null abweichende Ergebnis einer Auswahlfunktion f\u00fcr die Collection-Elemente zu erhalten, k\u00f6nnen wir <code>mapNotNull()<\/code> und <code>first()<\/code> verwenden. In 1.5.0 reicht daf\u00fcr ein einziger Aufruf der neuen Funktion <code>firstNotNullOf()<\/code>. Zusammen mit <code>firstNotNullOf()<\/code> f\u00fchren wir auch die <code>*orNull()<\/code>-Variante ein, die null zur\u00fcckgibt, wenn kein R\u00fcckgabewert vorhanden ist.<\/p>\n<p>Hier ist ein Beispiel, wie Sie damit Ihren Code verk\u00fcrzen k\u00f6nnen.<\/p>\n<p>Angenommen, Sie haben eine Klasse mit einer nullf\u00e4higen Eigenschaft, und Sie ben\u00f6tigen den ersten Nicht-Null-Wert aus einer Liste von Klasseninstanzen.<\/p>\n<pre class=\"kotlin-code\" data-highlight-only=\"true\" theme=\"idea\" indent=\"4\" style=\"visibility: hidden; padding: 36px 0;\">\nclass Item(val name: String?)\n<\/pre>\n<p>Sie k\u00f6nnen dies implementieren, indem Sie die Collection durchlaufen und pr\u00fcfen, ob die Eigenschaft nicht null ist:<\/p>\n<pre class=\"kotlin-code\" data-highlight-only=\"true\" theme=\"idea\" indent=\"4\" style=\"visibility: hidden; padding: 36px 0;\">\n\/\/ Option 1: manual implementation\nfor (element in collection) {\n    val itemName = element.name\n    if (itemName != null) return itemName\n}\nreturn null\n<\/pre>\n<p>Eine andere M\u00f6glichkeit ist, die bestehenden Funktionen <code>mapNotNull()<\/code> und <code>firstOrNull()<\/code> zu verwenden. Zu beachten ist dabei, dass <code>mapNotNull()<\/code> eine tempor\u00e4re Collection mit zus\u00e4tzlichem Speicherbedarf erstellt, was insbesondere bei gro\u00dfen Collections ins Gewicht f\u00e4llt. Daher kann hier auch eine Umwandlung in eine Sequenz erforderlich sein.<\/p>\n<pre class=\"kotlin-code\" data-highlight-only=\"true\" theme=\"idea\" indent=\"4\" style=\"visibility: hidden; padding: 36px 0;\">\n\/\/ Option 2: old stdlib functions\nreturn collection\n    \/\/ .asSequence() \/\/ Avoid creating intermediate list for big collections\n    .mapNotNull { it.name }\n    .firstOrNull()\n<\/pre>\n<p>Und so sieht es bei Verwendung der neuen Funktion aus:<\/p>\n<pre class=\"kotlin-code\" data-highlight-only=\"true\" theme=\"idea\" indent=\"4\" style=\"visibility: hidden; padding: 36px 0;\">\n\/\/ Option 3: new firstNotNullOfOrNull()\nreturn collection.firstNotNullOfOrNull { it.name }\n<\/pre>\n<p><a name = \"test-library-changes\"><\/a><\/p>\n<h2>\u00c4nderungen in der Testbibliothek<\/h2>\n<p>In den letzten Releases haben wir keine gr\u00f6\u00dferen Updates an der Kotlin-Testbibliothek <code>kotlin-test<\/code> vorgenommen. Diesmal gibt es jedoch einige lang erwartete \u00c4nderungen. Mit 1.5.0-RC k\u00f6nnen Sie verschiedene neue Funktionen ausprobieren:<\/p>\n<ul>\n<li>Eine einzige <code>kotlin-test<\/code>-Abh\u00e4ngigkeit in Multiplattform-Projekten.<\/li>\n<li>Automatische Auswahl eines Testframeworks f\u00fcr Kotlin\/JVM-Quellcode-Sets.<\/li>\n<li>Aktualisierte Assertion-Funktionen.<\/li>\n<\/ul>\n<h3>Abh\u00e4ngigkeit von kotlin-test in Multiplattform-Projekten<\/h3>\n<p>Wir arbeiten weiter am Konfigurationsprozess f\u00fcr Multiplattform-Projekte. In 1.5.0 haben wir das Einrichten einer Abh\u00e4ngigkeit von <code>kotlin-test<\/code> f\u00fcr alle Quellcode-Sets vereinfacht.<\/p>\n<p>Jetzt ist die <code>kotlin-test<\/code>-Abh\u00e4ngigkeit im gemeinsamen Test-Quellcode-Set die einzige Abh\u00e4ngigkeit, die Sie hinzuf\u00fcgen m\u00fcssen. Das Gradle-Plugin leitet daraus die entsprechende plattformspezifische Abh\u00e4ngigkeit f\u00fcr die anderen Quellcode-Sets ab:<\/p>\n<ul>\n<li><code>kotlin-test-junit<\/code> f\u00fcr JVM-Quellcode-Sets. Sie k\u00f6nnen auch zu <code>kotlin-test-junit-5<\/code> oder <code>kotlin-test-testng<\/code> wechseln, indem Sie diese explizit aktivieren (lesen Sie weiter, um zu erfahren, wie das geht).<\/li>\n<li><code>kotlin-test-js<\/code> f\u00fcr Kotlin\/JS-Quellcode-Sets.<\/li>\n<li><code>kotlin-test-common<\/code> und <code>kotlin-test-annotations-common<\/code> f\u00fcr gemeinsame Quellcode-Sets.<\/li>\n<li>F\u00fcr Kotlin\/Native-Quellcode-Sets ist kein zus\u00e4tzliches Artefakt erforderlich, da Kotlin\/Native integrierte Implementierungen der <code>kotlin-test<\/code>-API bereitstellt.<\/li>\n<\/ul>\n<h3>Automatische Auswahl eines Testframeworks f\u00fcr Kotlin\/JVM-Quellcode-Sets<\/h3>\n<p>Sobald Sie wie oben beschrieben die Abh\u00e4ngigkeit des gemeinsamen Test-Quellcode-Sets von <code>kotlin-test<\/code> deklariert haben, werden die JVM-Quellcode-Sets automatisch um die Abh\u00e4ngigkeit von JUnit 4 erg\u00e4nzt. Das war\u2019s! Sie k\u00f6nnen sofort mit dem Schreiben und Ausf\u00fchren von Tests loslegen!<\/p>\n<p>So sieht es in der Groovy-DSL aus:<\/p>\n<pre class=\"kotlin-code\" data-highlight-only=\"true\" theme=\"idea\" indent=\"4\" style=\"visibility: hidden; padding: 36px 0;\">\nkotlin {\n    sourceSets {\n        commonTest {\n            dependencies {\n                 \/\/ This brings the dependency\n                \/\/ on JUnit 4 transitively\n                implementation kotlin('test')\n            }\n        }\n    }\n}\n<\/pre>\n<\/p>\n<p>Und in der Kotlin-DSL:<\/p>\n<pre class=\"kotlin-code\" data-highlight-only=\"true\" theme=\"idea\" indent=\"4\" style=\"visibility: hidden; padding: 36px 0;\">\nkotlin {\n    sourceSets {\n        val commonTest by getting {\n            dependencies {\n                \/\/ This brings the dependency\n                \/\/ on JUnit 4 transitively\n                implementation(kotlin(&quot;test&quot;))\n            }\n        }\n    }\n}\n<\/pre>\n<p>Sie k\u00f6nnen auch zu JUnit 5 oder TestNG wechseln, indem Sie im Test-Task einfach eine Funktion aufrufen: <a href=\"https:\/\/docs.gradle.org\/current\/javadoc\/org\/gradle\/api\/tasks\/testing\/Test.html#useJUnitPlatform--\" target=\"_blank\" rel=\"noopener\"><code>useJUnitPlatform()<\/code><\/a> bzw. <a href=\"https:\/\/docs.gradle.org\/current\/javadoc\/org\/gradle\/api\/tasks\/testing\/Test.html#useTestNG--\" target=\"_blank\" rel=\"noopener\"><code>useTestNG()<\/code><\/a>.<\/p>\n<pre class=\"kotlin-code\" data-highlight-only=\"true\" theme=\"idea\" indent=\"4\" style=\"visibility: hidden; padding: 36px 0;\">\nkotlin {\n    jvm {\n        testRuns[&quot;test&quot;].executionTask.configure {\n            \/\/ enable TestNG support\n            useTestNG()\n            \/\/ or\n            \/\/ enable JUnit Platform (a.k.a. JUnit 5) support\n            useJUnitPlatform()\n        }\n    }\n}\n<\/pre>\n<p>Dies funktioniert auch in Nur-JVM-Projekten, wenn Sie die Abh\u00e4ngigkeit von <code>kotlin-test<\/code> hinzuf\u00fcgen.<\/p>\n<h3>Aktualisierte Assertion-Funktionen<\/h3>\n<p>1.5.0 enth\u00e4lt eine Reihe neuer Assertion-Funktionen sowie Verbesserungen an bestehenden Funktionen.<\/p>\n<p>Sehen wir uns zun\u00e4chst die neuen Funktionen an:<\/p>\n<ul>\n<li><code>assertIs&lt;T&gt;()<\/code> und <code>assertIsNot&lt;T&gt;()<\/code> pr\u00fcfen den Typ des Werts.<\/li>\n<li><code>assertContentEquals()<\/code> vergleicht den Inhalt von Containern wie Arrays, Sequenzen und beliebigen <code>Iterable<\/code>-Instanzen. Genauer gesagt wird gepr\u00fcft, ob <code>expected<\/code> und <code>actual<\/code> die gleichen Elemente in der gleichen Reihenfolge enthalten.<\/li>\n<li><code>assertEquals()<\/code> und <code>assertNotEquals()<\/code> f\u00fcr <code>Double<\/code> und <code>Float<\/code> haben neue \u00dcberladungen mit einem dritten Parameter: Pr\u00e4zision.<\/li>\n<li><code>assertContains()<\/code> pr\u00fcft das Vorhandensein eines Elements in einem Objekt, in dem der Operator <code>contains()<\/code> definiert ist: Array, Liste, Bereich usw.<\/li>\n<\/ul>\n<p>Das folgende kurze Beispiel zeigt die Verwendung dieser Funktionen:<\/p>\n<pre class=\"kotlin-code\" data-highlight-only=\"true\" theme=\"idea\" indent=\"4\" style=\"visibility: hidden; padding: 36px 0;\">\n@Test\nfun test() {\n    val expectedArray = arrayOf(1, 2, 3)\n    val actualArray = Array(3) { it + 1 }\n\n    val first: Any = actualArray[0]\n    assertIs&lt;Int&gt;(first)\n    \/\/ first is smart-cast to Int now\n    println(&quot;${first + 1}&quot;)\n\n    assertContentEquals(expectedArray, actualArray)\n    assertContains(expectedArray, 2)\n\n    val x = sin(PI)\n\n    \/\/ precision parameter\n    val tolerance = 0.000001\n\n    assertEquals(0.0, x, tolerance)\n}\n<\/pre>\n<p>Und nun zu den bestehenden Assertion-Funktionen: Jetzt ist es m\u00f6glich, <a href=\"https:\/\/kotlinlang.org\/docs\/composing-suspending-functions.html\" target=\"_blank\" rel=\"noopener\">Suspending-Funktionen<\/a> im Inneren der Lambda-Funktion aufzurufen, die an <code>assertTrue()<\/code>, <code>assertFalse()<\/code> und <code>expect()<\/code> \u00fcbergeben wird, da diese Funktionen jetzt <a href=\"https:\/\/kotlinlang.org\/docs\/inline-functions.html\" target=\"_blank\" rel=\"noopener\">inline<\/a> sind.<\/p>\n<h2>Probieren Sie alle Features von Kotlin 1.5.0 aus<\/h2>\n<p>Nutzen Sie mit 1.5.0-RC all diese modernen Kotlin-APIs in Ihren realen Projekten!<\/p>\n<p>Installieren Sie in IntelliJ IDEA oder Android Studio das Kotlin-Plugin 1.5.0-RC. Erfahren Sie, wie Sie <a href=\"https:\/\/kotlinlang.org\/docs\/install-eap-plugin.html\" target=\"_blank\" rel=\"noopener\">EAP-Plugin-Versionen erhalten<\/a> k\u00f6nnen.<\/p>\n<p>Kompilieren Sie Ihre vorhandenen Projekte mit 1.5.0-RC, um zu \u00fcberpr\u00fcfen, wie sie mit 1.5.0 funktionieren. Dank der <a href=\"https:\/\/blog.jetbrains.com\/kotlin\/2021\/03\/kotlin-1-5-0-m2-released\/\">neuen, vereinfachten Konfiguration f\u00fcr Preview-Versionen<\/a> m\u00fcssen Sie nur die Kotlin-Version auf <code>1.5.0-RC<\/code> \u00e4ndern und bei Bedarf <a href=\"https:\/\/kotlinlang.org\/docs\/eap.html#build-details\" target=\"_blank\" rel=\"noopener\">die Abh\u00e4ngigkeitsversionen anpassen<\/a>.<\/p>\n<p align=\"center\"><a class=\"jb-download-button\" title=\"Installieren\" href=\"https:\/\/kotlinlang.org\/docs\/install-eap-plugin.html\" target=\"_blank\" rel=\"noopener\">1.5.0-RC installieren<\/a><\/p>\n<p>Wie immer k\u00f6nnen Sie die neueste Version online auf dem <a href=\"https:\/\/play.kotlinlang.org\" target=\"_blank\" rel=\"noopener\">Kotlin Playground<\/a> ausprobieren.<\/p>\n<h2>Kompatibilit\u00e4t<\/h2>\n<p>Wie bei allen Feature-Releases werden mit Kotlin 1.5.0 einige Deprecation-Zyklen f\u00fcr zuvor angek\u00fcndigte \u00c4nderungen abgeschlossen. Alle diese F\u00e4lle wurden vom <a href=\"https:\/\/kotlinlang.org\/docs\/compatibility-guide-15.html\" target=\"_blank\" rel=\"noopener\">Sprachkomitee<\/a> sorgf\u00e4ltig gepr\u00fcft und sind im Kompatibilit\u00e4tsleitfaden f\u00fcr Kotlin 1.5 aufgef\u00fchrt. Sie k\u00f6nnen diese \u00c4nderungen auch in <a href=\"https:\/\/youtrack.jetbrains.com\/issues\/KT?q=Tag:%20language-committee-approved%20Target%20versions:%201.5.0-RC,%201.5.0-M2,%201.5.0-M1,%201.5.0\" target=\"_blank\" rel=\"noopener\">YouTrack<\/a> einsehen.<\/p>\n<h3>RC-Versionshinweise<\/h3>\n<p>Nachdem Kotlin 1.5.0 nun den Release-Candidate-Status erreicht hat, ist es Zeit f\u00fcr Sie, mit dem Kompilieren und Ver\u00f6ffentlichen zu beginnen! Im Gegensatz zu fr\u00fcheren Milestone-Releases sind mit Kotlin 1.5.0-RC erstellte Bin\u00e4rdateien garantiert mit Kotlin 1.5.0 kompatibel.<\/p>\n<h2>Geben Sie uns Feedback<\/h2>\n<p>Dies ist die letzte Gelegenheit f\u00fcr Sie, auf die n\u00e4chste Feature-Version Einfluss zu nehmen! Teilen Sie uns alle Probleme im <a href=\"https:\/\/kotl.in\/issue\" target=\"_blank\" rel=\"noopener\">Issue-Tracker<\/a> mit. Machen Sie Kotlin 1.5.0 besser \u2013 f\u00fcr sich selbst und die Community!<\/p>\n<p align=\"center\"><a class=\"jb-download-button\" title=\"Installieren\" href=\"https:\/\/kotlinlang.org\/docs\/install-eap-plugin.html\" target=\"_blank\" rel=\"noopener\">1.5.0-RC installieren<\/a><\/p>\n","protected":false},"author":1132,"featured_media":136573,"comment_status":"closed","ping_status":"closed","template":"","categories":[907],"tags":[21,6408,477],"cross-post-tag":[],"acf":[],"_links":{"self":[{"href":"https:\/\/blog.jetbrains.com\/de\/wp-json\/wp\/v2\/kotlin\/137759"}],"collection":[{"href":"https:\/\/blog.jetbrains.com\/de\/wp-json\/wp\/v2\/kotlin"}],"about":[{"href":"https:\/\/blog.jetbrains.com\/de\/wp-json\/wp\/v2\/types\/kotlin"}],"author":[{"embeddable":true,"href":"https:\/\/blog.jetbrains.com\/de\/wp-json\/wp\/v2\/users\/1132"}],"replies":[{"embeddable":true,"href":"https:\/\/blog.jetbrains.com\/de\/wp-json\/wp\/v2\/comments?post=137759"}],"version-history":[{"count":2,"href":"https:\/\/blog.jetbrains.com\/de\/wp-json\/wp\/v2\/kotlin\/137759\/revisions"}],"predecessor-version":[{"id":137761,"href":"https:\/\/blog.jetbrains.com\/de\/wp-json\/wp\/v2\/kotlin\/137759\/revisions\/137761"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/blog.jetbrains.com\/de\/wp-json\/wp\/v2\/media\/136573"}],"wp:attachment":[{"href":"https:\/\/blog.jetbrains.com\/de\/wp-json\/wp\/v2\/media?parent=137759"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blog.jetbrains.com\/de\/wp-json\/wp\/v2\/categories?post=137759"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blog.jetbrains.com\/de\/wp-json\/wp\/v2\/tags?post=137759"},{"taxonomy":"cross-post-tag","embeddable":true,"href":"https:\/\/blog.jetbrains.com\/de\/wp-json\/wp\/v2\/cross-post-tag?post=137759"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}