KotlinConf is bringing the Kotlin community together for the fifth time, from May 22 to 24, 2024, at the Bella Center in Copenhagen, Denmark!
KotlinConf’24 will feature one day of workshops followed by two consecutive days of content and networking, including sessions, expo booths, and other fun activities. Secure your tickets, organize your travel, and get ready to come together for the biggest Kotlin event around.
On May 22, 2024, you’ll have the opportunity to immerse yourself in one of six expert-led workshops covering some of the most popular Kotlin topics. Seats for each are limited, so register soon if you’d like to attend.
Choose your workshop:
Asynchronous Programming With Kotlin Coroutines by Sebastian Aigner and Roman Elizarov.
Kotlin Multiplatform Beyond the Basics by Garth Gilmour and Pamela Hill.
Functional Programming in Kotlin by Simon Vergauwen and Francisco Diaz Rodriguez.
Hands-On Kotlin Web Development with Ktor by Anton Arhipov, Pasha Finkelshtein and Leonid Stashevsky.
Mastering Kotlin Refactoring – Tools and Techniques by Duncan McGregor and Nat Pryce.
Reactive Spring Boot With Coroutines and Virtual Threads by Urs Peter.
KotlinConf tickets always go fast. The last conference was completely sold out around 4 months in advance, so we recommend getting your tickets now.
If you already use IntelliJ IDEA (2021.3, 2022.1, 2022.2), your IDE will suggest updating Kotlin to 1.8.0 automatically. You can also update manually for these IDEs by following these instructions.
For IntelliJ IDEA 2022.3, the Kotlin plugin 1.8.0 will be delivered with upcoming IntelliJ IDEA updates.
For Android Studio Flamingo, the Kotlin plugin 1.8.0 is bundled into the latest Canary. For Android Studio Electric Eel, the IDE plugin will be delivered with the upcoming Android Studio updates.
If you need the command-line compiler, download it from the GitHub release page.
If you already use IntelliJ IDEA 213, 221, or 222, the IDE will suggest updating Kotlin to 1.7.20 automatically. You can also update manually by following these instructions.
For Android Studio Dolphin (213), Electric Eel (221), and Flamingo (222), the Kotlin plugin 1.7.20 will be delivered with upcoming Android Studios updates.
If you need the command-line compiler, download it from the GitHub release page.
Building Android Apps With Jetpack Compose(Jetpack Compose로 Android 앱 빌드하기) – Florina Muntenescu
이 워크숍을 통해 기초를 단단히 다지고 상태, 레이아웃, 디자인 시스템 및 애니메이션을 사용하는 선언형 사고 방식의 기초를 학습할 수 있습니다. 또한 뷰 기반 앱에서 Compose로의 실제 마이그레이션 과정을 살펴보고, Jetpack Compose에서 레이아웃의 작동 방식을 상세히 알아보며 워크숍을 마무리할 예정입니다.
Kotlin Multiplatform Mobile in Production(프로덕션 단계에서 Kotlin Multiplatform Mobile의 활용) – Kevin Galligan, Tadeas Kriz, Russell Wolf
이 워크숍에서는 빌드 시스템 및 도구 통합, iOS 측 SDK 디자인, 팀 구조, ‘Kotlin으로 개발하는 사람’ 등 Kotlin Multiplatform Mobile을 프로덕션에 적용하는 몇 가지 실습 중심의 예시를 살펴봅니다.
테스트 주도 개발(TDD)과 관련한 실습 중심의 이 워크숍에서 TDD에 활용 가능한 Kotlin의 기능 및 TDD 방식이 Kotlin에 제공하는 이점을 살펴볼 예정입니다. 함수형 스타일이 테스트 및 디자인에 어떤 영향을 미칠까요? 모킹을 피할 수 있을까요? 과연 그렇게 하는 게 맞을까요? 테스트 중 타입 시스템의 역할은 무엇일까요? 워크숍을 통해 이와 같은 질문의 답을 함께 찾아보세요.
Building Scalable Microservices With Ktor and Kafka(Ktor 및 Kafka를 사용하여 확장 가능한 마이크로서비스 구축) – Anton Arhipov, Viktor Gamov
이 워크숍에서는 서버 측 개발을 위한 3가지 K(Kotlin 프로그래밍 언어, Ktor 서비스 프레임워크, 이벤트 스트리밍을 위한 Kafka)를 설명합니다. 워크숍을 마치면 다음과 같은 지식을 습득할 수 있습니다.
Ktor를 사용하여 유연한 RESTful 서비스를 만들고 배포하는 방법.
추가 구성이 필요한 외부 라이브러리와 Ktor를 통합하는 방법.
Kafka 스트리밍과 같은 다양한 도구를 사용하여 서비스를 유연하게 연결하는 방법.
Asynchronous Programming With Kotlin Coroutines(Kotlin 코루틴을 사용한 비동기 프로그래밍) – Svetlana Isakova, Sebastian Aigner, Roman Elizarov
이 워크숍에서는 Kotlin 코루틴을 활용하여 생산성을 향상하는 데 필요한 모든 것을 학습합니다. 워크숍을 완료하면 코루틴 관련 용어를 익히고, 일반적 문제를 발견하고 예방하는 방법을 이해할 수 있습니다. 또한 프로젝트에서 코루틴을 효과적으로, 자신감 있게 사용할 수 있습니다.
Reactive Spring Boot With Coroutines(코루틴을 사용한 반응형 Spring Boot) – Urs Peter
이 워크숍에서는 Spring Boot의 코루틴 지원이 미흡한 Webflux 접근 방식의 모든 단점을 제거하고, 복잡하지 않게 반응형 기능을 제공하는 방식을 학습할 수 있습니다.
이 워크숍을 통해 Jetpack Compose로 Android에서, Swift UI로 iOS, JetBrains Compose Web으로 웹에서, JetBrains Compose Desktop으로 데스크톱 JVM에서 실행되는 작은 애플리케이션을 개발합니다. 이러한 애플리케이션은 네이티브 룩앤필을 제공하고 완전히 테스트를 거쳐 일관성 있는 비즈니스 레이어를 재사용할 수 있습니다.
Kotlin을 사용한 함수형 프로그래밍 – Raúl Raja Martínez, Alejandro Serrano Mena, Simon Vergauwen
이 워크숍에서는 Kotlin 코드에 직접 적용 가능한 함수형 프로그래밍의 개념을 살펴봅니다. Arrow가 지원 라이브러리로 사용됩니다. 이 라이브러리는 함수형 스타일을 한층 잘 활용할 수 있도록 유용한 타입 및 확장자를 제공합니다.
We’re happy – no, strike that! – we’re thrilled, ecstatic, and overjoyed to announce that KotlinConf is back!
🌷 The next KotlinConf will take place in person in Amsterdam on April 12–14, 2023. Finally we’ll be able to get together again and share the exciting things going on with Kotlin.
Register now to join the Kotlin community at the event of the year. Workshops, talks, and fun are guaranteed! Get your tickets before they run out!
We’ll kick off KotlinConf with the first day of workshops – April 12, 2023. The seats for each workshop are limited, so please register soon if you are interested in attending.
One workshop can be bought in addition to the conference pass. Choose your favorite:
Building Android Apps With Jetpack Compose, by Florina Muntenescu
In this workshop, you’ll start by building a solid foundation and learn the fundamentals of declarative thinking, working with states, layouts, design systems, and animation. You’ll then walk through a practical migration of a View-based app to Compose, and finish by diving deeper into how layouts work in Jetpack Compose.
Kotlin Multiplatform Mobile in Production, by Kevin Galligan, Tadeas Kriz, and Russell Wolf
In this workshop, we’ll work through some hands-on examples of putting Kotlin Multiplatform Mobile into production, including build system and tooling integration, iOS-side SDK design, team structure and “Who writes Kotlin?”, and more.
Kotlin TDD Masterclass, by Nat Pryce and Duncan McGregor
In this hands-on Test Driven Development workshop, we’ll explore what Kotlin brings to TDD, and what TDD brings to Kotlin. How does a functional style affect testing and design? Can we avoid mocking, and should we? What role does the type system play when we have tests? Join us and find out.
Building Scalable Microservices With Ktor and Kafka, by Anton Arhipov and Viktor Gamov
In this workshop, we will cover the three Ks for server-side development: the Kotlin programming language, the Ktor services framework, and Kafka for event streaming. By the end of the workshop you will know:
How to create and deploy resilient RESTful services using Ktor.
How to integrate Ktor with external libraries that require additional configuration.
How to flexibly connect services using a variety of tools, such as Kafka streams.
Asynchronous Programming With Kotlin Coroutines, by Svetlana Isakova, Sebastian Aigner, and Roman Elizarov
In this workshop, you’ll learn everything you need to become productive with coroutines in Kotlin. By the end, you’ll have enhanced your coroutines-related vocabulary, understand how to spot and avoid common problems, and will be able to effectively and confidently use coroutines in your own projects.
Reactive Spring Boot With Coroutines, by Urs Peter
In this workshop, you’ll learn how Spring Boot’s Coroutine support wipes out all of the downsides of the ‘raw’ Webflux approach and provides you with reactive characteristics without the complexity.
Getting Started With Kotlin Multiplatform, by Romain Boisselle and Salomon Brys
In this workshop, we’ll be building a small application that runs on Android with Jetpack Compose, on iOS with Swift UI, on the web with JetBrains Compose Web, and on desktop JVMs with JetBrains Compose Desktop, providing a native look and feel while reusing a fully tested and coherent business layer.
Functional Programming in Kotlin, by Raúl Raja Martínez, Alejandro Serrano Mena, and Simon Vergauwen
In this workshop, we’ll look at concepts from functional programming that are directly applicable to Kotlin code. We’ll use Arrow as a supporting library, which includes many useful types and extensions to make a functional style even more pleasant.
KotlinConf is a community event, so we would love for you to take part. The call for papers is now open!
Submit a talk and share your experience, whether it’s about finding innovative ways to use Kotlin, the challenges you’ve faced, a framework you’ve created, or anything you’d like to share that could help others along their journey.
Kotlin 1.7.0 has been released. It unveils the Alpha version of the new Kotlin/JVM K2 compiler, stabilizes language features, and brings performance improvements for the JVM, JS, and Native platforms.
Here is a list of the major updates in this version:
The new Kotlin К2 compiler is in Alpha now, and it offers serious performance improvements. It is available only for the JVM, and none of the compiler plugins, including kapt, work with it yet.
If you already use IntelliJ IDEA or Android Studio Chipmunk (212), your IDE will suggest updating Kotlin to 1.7.0 automatically. You can also update manually for these IDEs by following these instructions.
For Intellij IDEA 2022.2, and Android Studio Dolphin (213) or Android Studio Electric Eel (221), the Kotlin plugin 1.7.0 will be delivered with upcoming Intellij IDEA and Android Studios updates.
Make sure that you have also updated the kotlinx libraries to compatible versions and specified version 1.7.0 of Kotlin in the build scripts of your existing projects.
If you need the command-line compiler, download it from the GitHub release page.
Kotlin 1.6.0 ist jetzt offiziell veröffentlicht – mit Stable-Status für abschließende when-Blöcke, dem Code-Coverage-Tool Kover und einem neuen Speichermanager für Kotlin/Native. Auch andere Neuerungen in der Sprache und den Standardbibliotheken, die in 1.5.30 veröffentlicht wurden, wurden in den Status Stable befördert. Vielen Dank für das Feedback, das Sie uns zukommen ließen. Wenn Sie diese neuen Features noch nicht ausprobiert haben – jetzt ist es höchste Zeit!
In diesem Blogbeitrag finden Sie einen Überblick über die folgenden Updates:
Neue Sprachmerkmale: versiegelte when-Anweisungen, suspendierende Funktionen und entsprechende Umwandlungen, Instanziierung von Annotationsklassen, verbesserte Typinferenz für reguläre und Builder-Typen.
Kotlin/JVM mit optimierten delegierten Eigenschaften und wiederholbaren Annotationen.
Kotlin/Native mit der Preview eines neuen Speichermodells, Xcode-13-Unterstützung, Kreuzkompilierung von Windows-Zielen, LLVM- und Linker-Updates, Leistungsupdates und einer einheitlichen Compiler-Plugin-ABI.
Optionale Deaktivierung des Herunterladens von Node.js und Yarn für Kotlin/JS.
Standardbibliothek mit neuen Funktionen für die Standardeingabe, stabiler typeOf()-Funktion, stabiler Duration-API und weiteren stabilen stdlib-Funktionen.
AbonnierenSie unser Blog, um keine Kotlin-Updates zu verpassen!
So führen Sie das Update durch
Wenn Sie IntelliJ IDEA oder Android Studio verwenden, haben Sie die Möglichkeit, automatisch auf die neue Kotlin-Version zu aktualisieren.
Wir haben Sprachmerkmale aus Kotlin 1.5.30 basierend auf Ihrem Feedback stabilisiert.
Abschließende (versiegelte) when-Anweisungen
Versiegeltes when ist eine lang erwartete Funktion des Kotlin-Compilers, die Sie warnt, wenn Ihre when-Anweisungen nicht abschließend sind, also nicht alle Möglichkeiten berücksichtigen. Dadurch wird Ihr Code sicherer, ohne eigene Funktionen für diesen Zweck schreiben zu müssen.
Kotlin hat when-Ausdrücke, die sich auf versiegelte Klassen, Enums und boolesche Typen bezogen, schon immer auf Vollständigkeit überprüft. Dies ist nützlich, wenn Sie Ihre Domäne mit diesen algebraischen Datentypen abbilden. Sie könnten beispielsweise in Ihrer App unterschiedliche Kontaktpräferenzen der Benutzer*innen als versiegelte Klassenhierarchie modellieren:
sealed class Contact {
data class PhoneCall(val number: String) : Contact()
data class TextMessage(val number: String) : Contact()
data class InstantMessage(val type: IMType, val user: String) : Contact()
}
Wenn Sie nun einen Ausdruck schreiben, der abhängig von der Kontakteinstellung ein unterschiedliches Ergebnis zurückgibt, meldet der Compiler einen Fehler, wenn Sie vergessen haben, alle Typen zu berücksichtigen, die in Ihrer App möglich sind:
fun Rates.computeMessageCost(contact: Contact): Cost =
when (contact) { // ERROR: 'when' expression must be exhaustive
is Contact.PhoneCall -> phoneCallCost
is Contact.TextMessage -> textMessageCost
}
Dies ist eine große Hilfe sowohl beim Schreiben des Codes als auch bei der späteren Wartung. Wenn Sie später eine weitere Kontaktoption hinzufügen, können Sie sich darauf verlassen, dass der Compiler Sie daran erinnert, die verschiedenen Kontaktpräferenzen überall in Ihrem Code zu berücksichtigen.
Vor Kotlin 1.6 wurde jedoch die when-Anweisung im folgenden Code erfolgreich kompiliert, obwohl versäumt wurde, den Versand einer Nachricht per Instant Messaging zu implementieren:
fun sendAnnouncement(contact: Contact, announcement: Announcement) {
when (contact) {
is Contact.PhoneCall -> schedulePhoneCall(contact.number, announcement)
is Contact.TextMessage -> sendTextMessage(contact.number, announcement)
}
}
Das Problem wurde nur von einer nachrangigen IDE-Inspektion gemeldet, ohne irgendwelche Meldungen vom Compiler. Ab Kotlin 1.6 wird die folgende Compiler-Warnung ausgegeben:
Non-exhaustive 'when' statements on sealed class/interface will be prohibited in 1.7. Add an 'is InstantMessage' branch or 'else' branch instead.
In Kotlin 1.7 wird dies als Fehler gewertet, damit solche Fälle nicht übersehen werden können. Im Ticket KT-47709 finden Sie eine genauere Erläuterung der Änderung und ihrer Auswirkungen.
Suspendierende Funktionen als Supertypen
Kotlin 1.6 stabilisiert die Unterstützung für die Implementierung von suspend-Funktionstypen als Superschnittstellen. Dies war eines der fehlenden Puzzleteile beim Design der Kotlin-Coroutinen.
Bei der Gestaltung von Kotlin-APIs ist es idiomatisch, Funktionstypen zu akzeptieren, wenn das Verhalten von Bibliotheksfunktionen anpassbar sein soll. Beispielsweise verfügt die Schnittstelle Job der API kotlinx.coroutines über eine Memberfunktion, die ungefähr so aussieht:
fun invokeOnCompletion(handler: () -> Unit)
Sie können diese Funktion bequem mit Lambdas wie nachAbschlussAufrufen { etwasTun() } verwenden. Wenn Sie eine Klasse haben, die auf den Abschluss reagieren soll, können Sie Ihren Code vereinfachen und optimieren, indem Sie den Funktionstyp () -> Unit direkt in Ihrer Klasse implementieren, sodass Sie keine zusätzliche Lambdafunktion benötigen:
class MyCompletionHandler : () -> Unit {
override fun invoke() { doSomething() }
}
Ab Kotlin 1.6 ist diese Optimierung mit suspendierenden Funktionen möglich. Nehmen wir an, Ihre API akzeptiert suspendierende Funktionstypen wie diese:
public fun launchOnClick(action: suspend () -> Unit) {}
In diesem Fall sind Sie nicht mehr darauf beschränkt, Lambdas und Referenzen auf suspendierende Funktionen an diesen Code zu übergeben. Sie können die entsprechenden suspendierenden Funktionstypen auch in einer Klasse implementieren:
class MyClickAction : suspend () -> Unit {
override suspend fun invoke() { doSomething() }
}
Umwandlungen in suspendierende Typen
Kotlin 1.6 befördert die Umwandlungen von regulären zu suspendierenden Funktionstypen in den stabilen Status. Wenn bei einem Parameter ein suspendierender Typ erwartet wird, können Sie jetzt einen geeigneten regulären Funktionstyp übergeben. Der Compiler führt die Umwandlung automatisch durch.
Dadurch wird eine kleine, aber störende Inkonsistenz beim Zusammenspiel zwischen regulären und suspendierenden Funktionen in Kotlin behoben. Wenn Sie eine Funktion höherer Ordnung haben, die eine suspendierende Funktion akzeptiert (Beispiel: ein collect-Aufruf auf einem Kotlin-Flow), müssen Sie zum Aufrufen nicht unbedingt ein Lambda wie im folgenden Code verwenden:
flow.collect { processItem(it) }
fun processItem(item: Item) { /* ... */ }
Stattdessen könnte es praktischer sein, eine Referenz auf die Funktion processItem an den collect-Aufruf zu übergeben – die Wirkung ist identisch.
flow.collect(::processItem)
Sie könnten dann eine Referenz auf Ihre Verarbeitungsfunktion in eine Variable extrahieren, um das Verhalten in Ihrem Code entsprechend anzupassen. Allerdings funktionierte dies in den Kotlin-Versionen vor 1.6 nicht. Dies liegt daran, dass Sie eine reguläre Funktion als Parameter übergeben, wo ein suspendierender Typ erwartet wird:
val processingFunction = ::processItem
flow.collect(processingFunction) // ERROR: Type mismatch
Der obige Code wird in Kotlin 1.6 einwandfrei kompiliert und funktioniert auch wie erwartet.
Verbesserte Typinferenz für rekursive generische Typen
Ab 1.6.0 kann der Kotlin-Compiler standardmäßig ein Typargument basierend nur auf den oberen Grenzen des entsprechenden Typparameters ableiten, wenn dieser ein rekursiver generischer Typ ist. Dies ermöglicht verschiedene Patterns mit rekursiven generischen Typen, die in Java häufig für Builder-APIs verwendet werden.
// Vor 1.5.30
val containerA = PostgreSQLContainer<nothing>(DockerImageName.parse("postgres:13-alpine")).apply {
withDatabaseName("db")
withUsername("user")
withPassword("password")
withInitScript("sql/schema.sql")
}
// Mit Compileroption in 1.5.30 oder standardmäßig ab 1.6.0
val containerB = PostgreSQLContainer(DockerImageName.parse("postgres:13-alpine"))
.withDatabaseName("db")
.withUsername("user")
.withPassword("password")
.withInitScript("sql/schema.sql")
Verbesserte Builder-Inferenz
In Kotlin 1.5.30 wurde die Compileroption -Xunrestricted-builder-inference eingeführt, um innerhalb von Builder-Lambdas auf Typinformationen über einen Builder-Aufruf zugreifen zu können. Konkret bedeutet dies die Möglichkeit, Aufrufe zu tätigen, die eine Instanz eines noch nicht bekannten Typs zurückgeben, z. B. get() in einem buildList()-Lambda.
Ab 1.6.0 müssen Sie nicht die Option -Xunrestricted-builder-inference angeben, um diese bisher unzulässigen Aufrufe zu tätigen. Mit der Compileroption -Xenable-builder-inference können Sie jetzt ohne Verwendung der Annotation @BuilderInference Ihre eigenen generischen Builder schreiben und Builder-Inferenzen automatisch aktivieren, wenn die reguläre Typinferenz keine Typinformationen ergibt.
Längere Unterstützung früherer API-Versionen
Ab Kotlin 1.6.0 können Sie bei der Entwicklung außer der aktuellen stabilen API-Version drei frühere Versionen (anstelle der bisherigen zwei) verwenden. Derzeit stehen Ihnen also die API-Versionen 1.3, 1.4, 1.5 und 1.6 zur Verfügung.
Kotlin/JVM
Wiederholbare Annotationen mit Laufzeiterhaltung.Wie Java 8 kennt auch Kotlin wiederholbare Annotationen. Ab Kotlin 1.6 ist diese Funktion Java-kompatibel. @kotlin.annotation.Repeatable akzeptiert jetzt jede Retention-Angabe und macht die Annotation sowohl in Kotlin als auch in Java wiederholbar. Außerdem werden wiederholbare Java-Annotationen jetzt auch auf Kotlin-Seite unterstützt.
Kotlin/Native
Ab sofort können Sie die experimentelle Version des neuen Kotlin/Native-Speichermanagers ausprobieren. Mit diesem Feature kommen wir unserem Ziel einer konsistenten Entwicklererfahrung bei Multiplattform-Projekten näher. Der neue Speichermanager hebt die bestehenden Beschränkungen für die gemeinsame Objektnutzung zwischen Threads auf und bietet Primitive für die nebenläufige Programmierung, die sicher sind, Lecks vermeiden und keine spezielle Verwaltung oder Annotationen von Seiten des Entwicklungsteams erfordern.
Sie können Xcode unbesorgt aktualisieren und an Ihren Kotlin-Projekten weiterarbeiten, da Kotlin/Native jetzt Xcode 13 unterstützt.
Kompilieren von Windows-Zielen auf beliebigen Hosts. Sie können die Windows-Ziele mingwX64 und mingwX86 auf jedem Host kompilieren, der Kotlin/Native unterstützt.
Wir haben die LLVM-Abhängigkeit, die Kotlin/Native unter der Haube verwendet, überarbeitet. Neben einer auf 11.1.0 aktualisierten LLVM-Version und einer verringerten Größe der Abhängigkeiten bietet dies einige weitere Vorteile.
Vereinheitlichung der Compiler-Plugin-ABI mit den JVM- und JS-IR-Backends. Jetzt kann das Gradle-Plugin für Kotlin Multiplatform das einbettbare Compiler-Jar, das für die JVM- und JS-IR-Backends verwendet wird, auch für Kotlin/Native verwenden. Sie können jetzt dieselben Compiler-Plugin-Artefakte für die Native-Plattform und andere unterstützte Plattformen verwenden.
Kotlin/JS
Für Buildvorgänge auf einem Server ohne Internetverbindung können Sie jetzt das Herunterladen von Node.js und Yarn für Kotlin/JS-Projekte deaktivieren und die auf dem Host vorinstallierten Instanzen verwenden.
Kover
Die genaue Ermittlung der Code-Coverage war vom ersten Kotlin-Release an eine Herausforderung. Einige großartige Tools wie JaCoCo verarbeiten Kotlin-Code, sind jedoch nicht vollständig in unsere Gradle-Toolchain und unsere Multiplattform-Projekte integriert. In dieser Kotlin-Version haben wir begonnen, dieses Problem anzupacken. Unser neues Gradle-Plugin Kover ermittelt die Code-Coverage von Kotlin-Code, der mit dem Kotlin/JVM-Compiler kompiliert wurde. Das Tool befindet es sich in einer frühen Entwicklungsphase und gilt als experimentell – wir freuen uns auf Ihr Feedback in GitHub.
Regex-Funktion zum Aufteilen von Zeichenfolgen in Sequenzen
Außerdem können Sie jetzt compareTo mit Infixnotation verwenden, und wir haben an der Konsistenz zwischen den replace()-Funktionen in JVM und JS gearbeitet.
Neue Funktionen für die Standardeingabe
In Kotlin 1.6.0 ist der Nicht-Null-Assertion-Operator !! nach dem Lesen einer Zeile von der Standardeingabe nicht mehr erforderlich. Dies vereinfacht den Einstieg für Neulinge und erleichtert das Unterrichten von Kotlin.
Wir bieten die folgenden neuen Möglichkeiten für das Lesen von der Konsole:
readln() löst eine Ausnahme aus, wenn das Dateiende erreicht wurde. Sie können diese Funktion verwenden, statt das Ergebnis von readLine() mit dem Operator !! auf null zu überprüfen.
Die neue Funktion readlnOrNull() ist eine Alternative, die null zurückgibt. Sie verhält sich also wie bisher readLine() – nur dass die Funktion jetzt einen passenderen Namen hat.
Diese Funktionen sind für JVM und Native verfügbar. Sie sind analog zu println() benannt – für Neueinsteiger*innen ist dies besonders hilfreich.
fun main() {
println("Input two integer numbers each on a separate line")
val num1 = readln().toInt()
val num2 = readln().toInt()
println("The sum of $num1 and $num2 is ${num1 + num2}")
}
Stabile Duration-API
Mithilfe Ihres Feedbacks haben wir die API für Zeiträume stabilisiert und den entsprechenden Roadmap-Eintrag geschlossen.
Die days-Komponente der Funktion toComponents ist jetzt vom Typ Long statt Int, um das Abschneiden von Werten zu vermeiden.
Die Enum DurationUnitist kein Typalias mehr. Es gibt keine Fälle, in denen es als Typalias für Java.util.concurrent.TimeUnit in der JVM verwendet wird.
Als Wunsch der Community sind Erweiterungseigenschaften wie Int.seconds wieder da. Um ihre Anwendbarkeit einzuschränken, sind sie nur im Companion-Objekt der Klasse Duration verfügbar.
import kotlin.time.Duration.Companion.seconds
fun main() {
//sampleStart
val duration = 5000.seconds
println("There are ${duration.inWholeMinutes} minutes in ${duration.inWholeHours} hours")
//sampleEnd
}
Stabiles typeOf()
In Kotlin 1.6.0 hat typeOf() den Status Stable. Der entsprechende Roadmap-Eintrag wurde geschlossen. Seit 1.3.40 war typeOf() auf der JVM-Plattform als experimentelle API verfügbar. Jetzt ist die Funktion auf jeder Kotlin-Plattform verfügbar und gibt einen beliebigen Kotlin-Typ, den der Compiler ableiten kann, als KType zurück.
inline fun <reified T> renderType(): String {
val type = typeOf<T>()
return type.toString()
}
fun main() {
val fromExplicitType = typeOf<Int>()
val fromReifiedType = renderType<List<Int>>()
}
Stabile Collection-Builder
Kotlin 1.6.0 befördert Collection-Builder-Funktionen wie buildMap(), buildList() und buildSet() in den Stable-Status. Von den Buildern zurückgegebene Collections sind jetzt im schreibgeschützten Zustand serialisierbar.
Stabile Bitrotation für Ganzzahlen
Die Funktionen rotateLeft() und rotateRight(), die die binäre Darstellung einer Zahl um die angegebene Anzahl von Bits nach links oder rechts rotieren, haben ab Kotlin 1.6.0 den Status Stable.
fun main() {
//sampleStart
val number: Short = 0b10001
println(number.rotateRight(2).toString(radix = 2)) // 100000000000100
println(number.rotateLeft(2).toString(radix = 2)) // 1000100
//sampleEnd
}
Stabile Regex-Funktion zum Aufteilen von Zeichenfolgen in Sequenzen
Eine weitere seit Kotlin 1.6.0 stabile Funktion ist splitToSequence() zum Aufteilen einer Zeichenfolge in eine Sequenz mithilfe eines regulären Ausdrucks.
fun main(){
//sampleStart
val colorsText = "green, red , brown&blue, orange, pink&green"
val regex = "[,\s]+".toRegex()
val mixedColor = regex.splitToSequence(colorsText)
.onEach { println(it) }
.firstOrNull { it.contains('&') }
println(mixedColor) // "brown&blue"
//sampleEnd
}
CompareTo in Infixnotation
Die Funktion Comparable.compareTo zum Vergleichen von zwei Objekten kann jetzt in Infixnotation aufgerufen werden:
class WrappedText(val text: String) : Comparable<WrappedText> {
override fun compareTo(other: WrappedText): Int =
this.text compareTo other.text
}
Einheitlichkeit zwischen JVM und JS bei replace() und replaceFirst()
Vor Kotlin 1.6.0 verhielten sich die Regex-Funktionen replace() und replaceFirst() auf JVM und JS unterschiedlich, wenn die Ersetzungszeichenfolge eine Gruppenreferenz enthielt. Das Verhalten von Kotlin/JS wurde an das Verhalten der JVM angepasst.
Kompatibilität
Wie bei allen Feature-Releases werden mit Kotlin 1.6.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.6 aufgeführt. Sie können diese Änderungen auch in YouTrack einsehen.
Installation von Kotlin 1.6.0
Wenn Sie IntelliJ IDEA oder Android Studio verwenden, schlägt Ihnen die IDE automatisch die Aktualisierung auf Kotlin 1.6.0 vor. Alternativ ist auch eine manuelle Aktualisierung gemäß dieser Anleitung möglich.
Sie können die neuesten Versionen dieser IDEs herunterladen, um eine umfassende Kotlin-Unterstützung zu erhalten:
IntelliJ IDEA – zur Entwicklung von Kotlin-Anwendungen für verschiedene Plattformen.
Android Studio – zur Entwicklung von Android-Apps und plattformübergreifenden Mobilanwendungen.
Achten Sie darauf, auch die kotlinx-Bibliotheken auf die kompatiblen Versionen zu aktualisieren und die Kotlin-Version 1.6.0 in den Build-Skripten Ihrer bestehenden Projekte anzugeben.
Den Befehlszeilen-Compiler können Sie bei Bedarf von der GitHub-Release-Seite herunterladen.
Melden Sie Probleme in unserem Issue-Tracker, YouTrack.
Bleiben Sie stets auf dem neuesten Stand der Kotlin-Entwicklung! Abonnieren Sie unsere Kotlin-Updates, indem Sie das Formular rechts neben diesem Beitrag ausfüllen.
Kotlin 1.6.0 is now officially released with Stable exhaustive whens, Kover, and a new memory manager for Kotlin/Native. Other language and standard library features released in 1.5.30 became Stable as well. Thanks for the feedback you’ve shared with us. If you still haven’t tried these new features out, now is the time!
In this blog post, you can find an overview of the following updates:
Language features with sealed when statements, suspending functions and suspend conversions, instantiation of annotation classes, improved regular type inference and builder type inference.
Kotlin/JVM with optimized delegated properties and repeatable annotations.
Kotlin/Native with a preview of a new memory model, Xcode 13 support, a cross-compilation of Windows targets, LLVM and linker updates, performance updates, and unified compiler plugin ABI.
Option to disable downloading of Node.js and Yarn for Kotlin/JS.
We stabilized features from Kotlin 1.5.30 based on your feedback.
Sealed (exhaustive) when statements
Sealed when is a long-awaited feature that makes the Kotlin compiler warn you if your when statements are not exhaustive. This makes your code safer without having to introduce your own functions.
Kotlin has always been exhaustive in checking whenexpressions for sealed classes, enums, and Boolean types. It is useful when you model your domain with those algebraic data types. For example, you might have different contract preferences for users of your app modeled as a sealed class hierarchy:
sealed class Contact {
data class PhoneCall(val number: String) : Contact()
data class TextMessage(val number: String) : Contact()
data class InstantMessage(val type: IMType, val user: String) : Contact()
}
Now, if you write an expression that returns a different result based on different contact preference, the compiler will flag an error if you forget to handle all of the types you have in your app:
fun Rates.computeMessageCost(contact: Contact): Cost =
when (contact) { // ERROR: 'when' expression must be exhaustive
is Contact.PhoneCall -> phoneCallCost
is Contact.TextMessage -> textMessageCost
}
This is a great help, both in writing code and for future maintenance. If you add a different type of contact preference later, you know that the compiler will make sure you have not forgotten to handle the different types of contact preferences all around your code.
However, before Kotlin 1.6, the following code that uses whenstatements successfully compiles, even though it totally forgets to handle sending an announcement to your users via instant message:
fun sendAnnouncement(contact: Contact, announcement: Announcement) {
when (contact) {
is Contact.PhoneCall -> schedulePhoneCall(contact.number, announcement)
is Contact.TextMessage -> sendTextMessage(contact.number, announcement)
}
}
Only a weak IDE inspection was reported, without any messages from the compiler. Starting from Kotlin 1.6, it produces the following compiler warning:
Non-exhaustive 'when' statements on sealed class/interface will be prohibited in 1.7. Add an 'is InstantMessage' branch or 'else' branch instead.
In Kotlin 1.7 it will become an error, leaving no chance to accidentally forget it. Please see KT-47709 for a more detailed explanation of the change and its effects.
Suspending functions as supertypes
Kotlin 1.6 stabilizes support for implementing suspend functional types as super interfaces. It was one of the missing pieces in the Kotlin coroutines design.
When you design Kotlin APIs, it is idiomatic to accept functional types when you need to customize the behavior of various library functions. For example, kotlinx.coroutines API has a member function in its Job interface that looks similar to this:
fun invokeOnCompletion(handler: () -> Unit)
You can conveniently use this function with lambdas like invokeOnCompletion { doSomething() }. If you have a class that you wanted to handle the completion with, you can streamline and optimize your code by implementing the functional type () -> Unit directly in your class without creating an additional lambda:
class MyCompletionHandler : () -> Unit {
override fun invoke() { doSomething() }
}
Starting from Kotlin 1.6 this optimization is possible with suspending functions. If your APIs accept suspending functional types, like this:
public fun launchOnClick(action: suspend () -> Unit) {}
… then you are not limited to passing lambdas and suspending function references to this code anymore. You can implement the corresponding suspending functional types in a class, too:
class MyClickAction : suspend () -> Unit {
override suspend fun invoke() { doSomething() }
}
Suspend conversions
Kotlin 1.6 stabilizes conversions from regular to suspending functional types. You can now pass any expression of a suitable regular functional type where suspending is expected as a parameter. The compiler will perform a conversion automatically.
This fixes a small but annoying inconsistency in the interaction between regular and suspending functions in Kotlin. In you have a higher-order function that accepts a suspending function, like a collect call on a Kotlin Flow, then instead of using a lambda to call it, like this:
flow.collect { processItem(it) }
fun processItem(item: Item) { /* ... */ }
… you might find it convenient to pass a reference to the processItem function to the collect call to the same effect:
flow.collect(::processItem)
You would then extract a reference to your processing function into a variable in order to customize the behavior in your code. However, that didn’t work in Kotlin versions prior to 1.6. This is because you have a regular function that is being passed as a parameter of a suspending type:
val processingFunction = ::processItem
flow.collect(processingFunction) // ERROR: Type mismatch
In Kotlin 1.6, the above code compiles and works, too.
Improved type inference for recursive generic types
From 1.6.0, the Kotlin compiler can infer a type argument based only on the upper bounds of the corresponding type parameter if it is a recursive generic by default. This makes it possible to create various patterns with recursive generic types that are often used in Java to make builder APIs.
// Before 1.5.30
val containerA = PostgreSQLContainer<nothing>(DockerImageName.parse("postgres:13-alpine")).apply {
withDatabaseName("db")
withUsername("user")
withPassword("password")
withInitScript("sql/schema.sql")
}
// With compiler option in 1.5.30 or by default starting with 1.6.0
val containerB = PostgreSQLContainer(DockerImageName.parse("postgres:13-alpine"))
.withDatabaseName("db")
.withUsername("user")
.withPassword("password")
.withInitScript("sql/schema.sql")
Builder inference improvements
Kotlin 1.5.30 introduced the -Xunrestricted-builder-inference compiler option, which made type information about a builder call available to get inside builder lambdas. Namely, it introduced the ability of making calls that return an instance of a not yet inferred type, such as get() inside a buildList() lambda.
Starting with 1.6.0, you don’t need to specify -Xunrestricted-builder-inference to make previously prohibited calls. With the -Xenable-builder-inference compiler option, you can now also write your own generic builders without applying the @BuilderInference annotation and automatically enable builder inference if regular type inference cannot resolve type information.
Supporting previous API versions for a longer period
Starting with Kotlin 1.6.0, you can now develop using three previous API versions instead of two (along with the current stable one). Currently, this includes API versions 1.3, 1.4, 1.5, and 1.6.
Kotlin/JVM
Repeatable annotations with runtime retention.Kotlin, like Java 8, has repeatable annotations. With Kotlin 1.6, the feature is compatible with Java, and @kotlin.annotation.Repeatable now accepts any retention and makes the annotation repeatable both in Kotlin and Java. Java repeatable annotations are now also supported from the Kotlin side.
Kotlin/Native
Now you can try the Experimental version of the new Kotlin/Native memory manager. With this feature we are moving closer to providing a consistent developer experience in multiplatform projects. This means that the new memory manager lifts the existing restrictions on object sharing between threads and provides fully leak-free concurrent programming primitives that are safe and don’t require any special management or annotations from the developers.
You can freely update your Xcode and continue working on your Kotlin projects, as Kotlin/Native now supports Xcode 13.
Compilation of Windows targets on any host. You can compile Windows targets mingwX64 and mingwX86 on any host that supports Kotlin/Native.
We’ve reworked the LLVM dependency that Kotlin/Native uses under the hood. This brings some benefits along with an updated LLVM version to 11.1.0 and decreased dependency size.
Unified compiler plugin ABI with JVM and JS IR backends. Now, the Kotlin Multiplatform Gradle plugin is able to use the embeddable compiler jar – the one used for JVM and JS IR backends – for Kotlin/Native. You can now use the same compiler plugin artifacts for Native and other supported platforms.
Kotlin/JS
For building on a server without internet connectivity, you can now disable downloading Node.js and Yarn for Kotlin/JS projects and use the instances already installed on the host.
Kover
Since the first release, precise measurement of code coverage has been a challenge. Some great tools like JaCoCo work with Kotlin code, but they are not fully integrated with our Gradle toolchain and multiplatform projects. In this Kotlin release, we have started to fix this issue. Meet Kover, our new Gradle plugin that measures code coverage for Kotlin code built with the Kotlin/JVM compiler. Now it is in the early development stage and is experimental – we would appreciate your feedback on it in GitHub.
Regex function for splitting a string into a sequence
We’ve also added the ability to call compareTo in infix notation and invested in providing a consistent experience with replace() functions on JVM and JS.
New functions for standard input
In Kotlin 1.6.0, we got rid of the need to use the not-null assertion operator !! after reading a line from the standard input in order to improve the experience for newcomers and simplify teaching Kotlin.
We provide new functions for reading from the console with the following experience:
readln() throws an exception when EOF has been reached. Use this function instead of checking the result of readLine() for null with the !! operator.
The new readlnOrNull() is a null-returning alternative. It behaves in the same way as the former readLine() but has a more representative name.
These functions are now available for JVM and Native. The naming convention for these functions is now consistent with the println() counterpart, which is especially important for newcomers.
fun main() {
println("Input two integer numbers each on a separate line")
val num1 = readln().toInt()
val num2 = readln().toInt()
println("The sum of $num1 and $num2 is ${num1 + num2}")
}
The days component of the toComponents function now has the Long type instead of Int to avoid cutting off values.
The DurationUnitenum is now not a type alias. There are no cases of using it as a type alias for java.util.concurrent.TimeUnit on JVM.
In response to community feedback, we’re bringing back extension properties like Int.seconds. To limit their applicability, they are available only in the Companion of the Duration class.
import kotlin.time.Duration.Companion.seconds
fun main() {
//sampleStart
val duration = 5000.seconds
println("There are ${duration.inWholeMinutes} minutes in ${duration.inWholeHours} hours")
//sampleEnd
}
Stable typeOf()
Kotlin 1.6.0 brings StabletypeOf() and closes the corresponding roadmap item. Since 1.3.40, typeOf() has been available on the JVM platform as an experimental API, and now you can use it on any Kotlin platform and get a KType representation of any Kotlin type that the compiler can infer.
inline fun <reified T> renderType(): String {
val type = typeOf<T>()
return type.toString()
}
fun main() {
val fromExplicitType = typeOf<Int>()
val fromReifiedType = renderType<List<Int>>()
}
Stable collection builders
Kotlin 1.6.0 promotes collection builder functions – buildMap(), buildList(), and buildSet()– to Stable. Collections returned by the builders are now serializable in their read-only state.
Stable bit rotation operations for integers
In Kotlin 1.6.0, the rotateLeft() and rotateRight() functions, which rotate the binary representation of the number left or right by the specified number of bits, became Stable.
fun main() {
//sampleStart
val number: Short = 0b10001
println(number.rotateRight(2).toString(radix = 2)) // 100000000000100
println(number.rotateLeft(2).toString(radix = 2)) // 1000100
//sampleEnd
}
Stable Regex function for splitting a string into a sequence
Kotlin 1.6.0 also stabilizes splitToSequence() – a function for regular expressions that splits a string into a sequence.
fun main(){
//sampleStart
val colorsText = "green, red , brown&blue, orange, pink&green"
val regex = "[,\s]+".toRegex()
val mixedColor = regex.splitToSequence(colorsText)
.onEach { println(it) }
.firstOrNull { it.contains('&') }
println(mixedColor) // "brown&blue"
//sampleEnd
}
compareTo in infix notation
We’ve added the ability to call the Comparable.compareTo function in infix notation to compare two objects for order:
class WrappedText(val text: String) : Comparable<WrappedText> {
override fun compareTo(other: WrappedText): Int =
this.text compareTo other.text
}
Consistent replace() and replaceFirst() on JVM and JS
Before Kotlin 1.6.0, the replace() and replaceFirst() Regex functions behaved differently on JVM and JS when the replacement string contained a group reference. The behavior on Kotlin/JS is now consistent with that on JVM.
Compatibility
As with all feature releases, some deprecation cycles of previously announced changes are coming to an end with Kotlin 1.6.0. All of these cases were carefully reviewed by the language committee and are listed in the Compatibility Guide for Kotlin 1.6. You can also explore these changes on YouTrack.
How to install Kotlin 1.6.0
If you’re using IntelliJ IDEA or Android Studio, your IDE will suggest updating Kotlin to 1.6.0 automatically. Alternatively, you can update manually by following these instructions.
You can download the latest versions of these IDEs to get extensive support for Kotlin:
IntelliJ IDEA – for developing Kotlin applications for various platforms.
Android Studio – for developing Android and cross-platform mobile applications.
Make sure that you have also updated the kotlinx libraries to the compatible versions and specified Kotlin 1.6.0 in the build scripts of your existing projects.
If you need the command-line compiler, download it from the Github release page.
Since Kotlin 1.5.30 is the last incremental release before Kotlin 1.6.0, it includes many experimental language and standard library features that we are planning to release in Kotlin 1.6.0. Give them a try and share your feedback with us, you can really influence the final result! These experimental features include sealed when statements, changes to opt-in requirements, instantiation of annotation classes, improvements to the Duration and Regex stdlib APIs, and more.
With Kotlin 1.5.30, you can also enjoy native support for Apple silicon, the promotion of the Kotlin/JS IR backend to Beta, the ability to use custom cinterop libraries in the shared native code of multiplatform applications, support for Java toolchains provided by the Kotlin Gradle plugin, and much more.
This blog post provides an overview of the updates in this release:
Language improvements, including sealed when statements, support for suspend functions as supertypes, and changes to opt-in requirements.
Multiplatform improvements, including the ability to use custom cinterop libraries in shared native code and support for XCFrameworks as an output format.
Kotlin/JVM improvements, including instantiation of annotation classes and improved configuration of nullability annotation support.
Kotlin/Native improvements, including native support for Apple silicon and an improved Kotlin DSL for the CocoaPods Gradle plugin.
Kotlin/JS IR improvements, including the promotion of the JS IR backend to Beta and a better debugging experience for the new backend.
Gradle improvements, including support for Java toolchains and easier ways to explicitly set the Kotlin daemon’s JVM arguments.
Stay up to date with information about the latest Kotlin features! Subscribe to receive Kotlin updates by filling out the form to the right of this post.
Language
The Kotlin roadmap includes adding support for sealed when statements, releasing opt-in annotations, improving type inference, and stabilizing builder inference.
Kotlin 1.5.30 takes a step down this road by providing a preview of these features, whose release is planned for 1.6.0.
Sealed when statements
Sealed when is a long awaited feature with more than 280 votes in YouTrack. If you enable this feature in 1.5.30, the Kotlin compiler will warn if one of your when statements is not exhaustive. This will make your code safer without you having to introduce your own functions.
Kotlin 1.5.30 provides a preview of an ability to use suspend functional types as super interfaces, although it has some limitations. It’s one of the missing pieces in the Kotlin coroutines design.
class MyClass: suspend () -> Unit {
override suspend fun invoke() { TODO() }
}
Presents new rules for using and declaring opt-in requirement annotations on different targets.
Requires opt-in even for implicit usages of an experimental API. For example, if the function’s return type is marked as an experimental API element, a usage of the function requires you to opt-in even if the declaration is not marked as requiring an opt-in explicitly.
// Library code
@RequiresOptIn(message = "This API is experimental.")
@Retention(AnnotationRetention.BINARY)
@Target(AnnotationTarget.CLASS)
annotation class MyDateTime // Opt-in requirement annotation
@MyDateTime
class DateProvider // A class requiring opt-in
// Client code
// Warning: experimental API usage
fun createDateSource(): DateProvider { /* ... */ }
fun getDate(): Date {
val dateSource = createDateSource() // Also warning: experimental API usage
// ...
}
Improvements to type inference on recursive generic types
With type inference on recursive generic types enabled, the Kotlin 1.5.30 compiler can infer a type argument based only on the upper bounds of the corresponding type parameter if it is a recursive generic. This makes it possible to create various patterns with recursive generic types that are often used in Java to make builder APIs.
With eliminating builder inference restrictions enabled, Kotlin 1.5.30 removes a builder inference restriction. Not only can you specify the type information that builder inference can infer, but you can also use the get function on it. For example, you can call get() inside a lambda argument of buildList() without explicitly specified type arguments.
Kotlin Multiplatform
Kotlin 1.5.30 includes the following improvements for Kotlin Multiplatform:
Support for XCFrameworks as an output format for all Kotlin Multiplatform projects. XCFrameworks help gather logic for all the target platforms and architectures in a single bundle and don’t require removing unnecessary architectures before publishing the application to AppStore.
New default publishing setup for Android artifacts. This setup will be compatible with any build type (like debug or release) by default. Before 1.5.30, the metadata generated by the maven-publish Gradle plugin when publishing a multiplatform library for Android included the build type attribute for every published Android variant. This made it compatible only with the same build type used by the library consumer.
Kotlin/JVM
With Kotlin 1.5.30, Kotlin/JVM gets the following updates:
Instantiation of annotation classes. If you enable this feature, you can call constructors of annotation classes in arbitrary code to obtain a resulting instance. This feature covers the same use cases as the Java convention, which enables the implementation of an annotation interface. Learn more about instantiation of annotation classes in this KEEP.
annotation class InfoMarker(val info: String)
fun processInfo(marker: InfoMarker) = ...
fun main(args: Array<String>) {
if (args.size != 0)
processInfo(getAnnotationReflective(args))
else
processInfo(InfoMarker("default"))
}
Kotlin/Native
Kotlin 1.5.30 provides the following improvements for Kotlin/Native:
Native support for Apple silicon. You can now build applications on Apple silicon hardware for all targets that are supported on Intel-based Macs, without having to use the Rosetta translation environment. New targets introduced in 1.5.30 – macosArm64, iosSimulatorArm64, watchosSimulatorArm64, and tvosSimulatorArm64 – make it possible to run Kotlin code on Apple silicon natively.
Improved Kotlin DSL for the CocoaPods Gradle plugin. Kotlin 1.5.30 improves CocoaPods configuration by providing a new DSL format for frameworks that is identical to a framework definition for Apple targets. You can define whether it is a static or dynamic type, enable the explicit export of dependencies and the Bitcode embedding, and configure other options.
Deprecation of linkage to DLLs without import libraries for MinGW (Windows). This deprecation is the result of the switch to the LLD linker, which has better performance and other improvements. Feel free to share your thoughts and concerns about the transition to the LLD linker in this YouTrack issue.
Support for Java toolchains. Gradle 6.7 introduced support for Java toolchains, which make it easy to select a JDK for project compilation. Just declare the version you need in the build script and Gradle does the rest, finding it on your host machine or even downloading and installing it if it’s not there yet. The Kotlin Gradle plugin supports Java toolchains for Kotlin/JVM compilation tasks. For Gradle versions 6.1-6.6, set a JDK home with the UsesKotlinJavaToolchain interface.
Easier ways to explicitly specify Kotlin daemon JVM arguments. If nothing is specified for the Kotlin daemon, it inherits arguments from the Gradle daemon. You can now also specify arguments for a specific task, as well as for the Kotlin extension, as a single line in build.gradle.kts or gradle.properties.
Kotlin 1.5.30 provides a preview of API improvements. The output of Duration.toString() is now more readable. For example, Duration.minutes(920).toString() produces 15h 20m instead of the previous 920m.
A negative duration is now prefixed with a minus sign (-), and it is surrounded by parentheses if it consists of multiple components: -12m and -(1h 30m).
parse() parses Duration objects from strings formatted as Duration’s toString() or from strings representing ISO 8601 durations (such as toIsoString() outputs).
parseIsoString() parses Duration objects from strings representing ISO 8601 durations.
*OrNull() counterparts for both functions.
import kotlin.time.Duration
import kotlin.time.ExperimentalTime
@ExperimentalTime
fun main() {
//sampleStart
val isoFormatString = "PT1H30M"
val defaultFormatString = "1h 30m"
println(Duration.parse(isoFormatString)) // "1h 30m"
println(Duration.parse(defaultFormatString)) // "1h 30m"
//sampleEnd
}
Regex API improvements
Kotlin 1.5.30 provides new experimental functions for regular expressions:
matchesAt() checks whether a regex has a match in the specified position of a String.
matchAt() returns the match if one is found.
fun main(){
//sampleStart
val releaseText = "Kotlin 1.5.30 is released!"
val versionRegex = "\d[.]\d[.]\d+".toRegex()
println(versionRegex.matchAt(releaseText, 0)) // "null"
println(versionRegex.matchAt(releaseText, 7)?.value) // "1.5.30"
//sampleEnd
}
splitToSequence() is a lazy counterpart of split(). It splits the string around matches of the given regex, but returns the result as a Sequence. A similar function has also been added to CharSequence.
fun main(){
//sampleStart
val colorsText = "green, red , brown&blue, orange, pink&green"
val regex = "[,\s]+".toRegex()
val mixedColor = regex.splitToSequence(colorsText)
.onEach { println(it) }
.firstOrNull { it.contains('&') }
println(mixedColor) // "brown&blue"
//sampleEnd
}
You can download the latest versions of these IDEs to get extensive support for Kotlin:
IntelliJ IDEA – for developing Kotlin applications for various platforms.
Android Studio – for developing Android and cross-platform mobile applications.
Make sure that you have also updated the kotlinx libraries to compatible versions and specified version 1.5.30 of Kotlin in the build scripts of your existing projects.
If you need the command-line compiler, download it from the Github release page.
Stay up to date with information about the latest Kotlin features! Subscribe to receive Kotlin updates by filling out the form to the right of this post.
The 1.5.30 release is approaching, and now we’re presenting the release candidate with the updated opt-in requirements, Kotlin/JS IR backend in Beta, support for Java toolchains in the Gradle plugin, improvements to the Regex and Duration API in the standard library, and more. Try it and report any issues you face to help us prepare the final release.
We’ve unveiled the first set of Kotlin 1.5.30 features with the 1.5.30-M1 preview. In this post, we’ll briefly describe some more of the new features that you can try with Kotlin 1.5.30-RC:
Kotlin’s opt-in requirement mechanism has been available in the Experimental state for quite some time, and releasing it as Stable is on our roadmap. In 1.5.30, we’re changing the behavior of the opt-in requirements to make it more consistent and less error-prone:
An opt-in is now required for implicit usages of the marked API, for example, if it’s used as a function’s return type.
Opt-in annotations are now prohibited on more declarations, including local variables, value parameters, backing fields, and getters.
Overriding methods can only have opt-in annotations that are present on their basic declarations.
Opt-in annotations can’t have TYPE and TYPE_PARAMETER targets.
Instantiation of annotation classes
The ability to create instances of annotation classes by calling their constructors is another improvement on the Kotlin roadmap. In 1.5.30-RC, we’re adding the opt-in support for this ability to the JVM.
To allow creation of annotation instances with constructors, switch to the language version 1.6 by adding the -language-version 1.6 compiler option. You can find more details about this feature in this KEEP.
JS IR backend in Beta
The IR-based backend for the Kotlin/JS compiler has been in Alpha since Kotlin 1.4.0. We never stopped working on it, and in 1.5.30 it will become Beta. This means that we don’t expect breaking changes anymore and its future development will be mainly focused on stabilization.
Report migration issues to our issue tracker, YouTrack.
Gradle: Java toolchain support and JVM options for Kotlin daemon in the build script
Gradle 6.7 introduced the support for Java toolchains – an easy way to select a JDK for the project compilation. Just declare the version you need in the build script, and Gradle does the rest, finding it on your host or even downloading and installing it if it’s not there yet.
Kotlin 1.5.30-RC enables Java toolchain support for Kotlin compilation tasks:
kotlin {
toolchain {
(this as JavaToolchainSpec).languageVersion.set(JavaLanguageVersion.of(<MAJOR_JDK_VERSION>)
}
}
Other Gradle-related improvements include new ways to provide JVM options for the Kotlin Gradle daemon. Now you can specify them in a separate line in gradle.properties:
Kotlin’s Regex API is receiving new experimental functions:
matchesAt() checks if a regex has a match in the specified position of a String. It’s accompanied by matchAt() that returns the match itself if it is found.
val releaseText = "Kotlin 1.5.30 is coming!"
// regular expression: one digit, dot, one digit, dot, one or more digits
val versionRegex = "\d[.]\d[.]\d+".toRegex()
println(versionRegex.matchesAt(releaseText, 7)) // "true"
println(versionRegex.matchAt(releaseText, 7)?.value) // "1.5.30"
splitToSequence() – a lazy counterpart of split() – splits the string around matches of the given regex, but returns the result as a Sequence. A similar function is also added to CharSequence.
val phoneNumber = "+7 (123) 456-78-90"
val regex = "[ ()-]+".toRegex()
val parts = phoneNumber.splitToSequence(regex)
// or
// val parts = regex.splitToSequence(phoneNumber)
// any processing operation on parts are executed lazily
The experimental Duration API has also been updated in 1.5.30-RC:
The output of Duration.toString() has become more readable. For example, Duration.minutes(2415).toString() produces 1d 16h 15m instead of 40.3h.
Duration also receives new functions for parsing from strings:
parse() parses Duration objects from strings formatted as Duration’s toString() or strings representing ISO 8601 durations (such as toIsoString() outputs).
parseIsoString() parses Duration objects from strings representing ISO 8601 durations. Both parsing functions come with *OrNull() counterparts.
If you use the Early Access Preview update channel, the IDE will suggest updating to 1.5.30-RC automatically once it is out.
If you use the Stable update channel, you can change the channel to Early Access Preview at any time by selecting Tools | Kotlin | Configure Kotlin Plugin Updates in your IDE, then you’ll be able to install the latest preview release. Check out these instructions for details.
You can always download the latest versions of these IDEs to get extensive support for Kotlin:
IntelliJ IDEA for developing Kotlin applications for a variety of platforms.
Android Studio for developing Android and cross-platform mobile applications.
Note: the latest version of IntelliJ IDEA – 2021.2 – doesn’t support Kotlin 1.5.30 previews. If you have already upgraded to this version, you can easily install the previous version (2021.1) using the JetBrains Toolbox App and try Kotlin 1.5.30-RC in that version.