•Non-local break and continue •Multi-dollar interpolation •Guard conditions in when-with-subject expressions •Improved exhaustiveness checks for when expressions with sealed classes
"Interfaces in this library are experimental" ) annotation class UnstableApi() @SubclassOptInRequired(UnstableApi :: class) interface CoreLibraryApi interface MyImplementation : CoreLibraryApi Library User code
"Interfaces in this library are experimental" ) annotation class UnstableApi() @SubclassOptInRequired(UnstableApi :: class) interface CoreLibraryApi interface MyImplementation : CoreLibraryApi Library User code
"Interfaces in this library are experimental" ) annotation class UnstableApi() @SubclassOptInRequired(UnstableApi :: class) interface CoreLibraryApi @OptIn(UnstableApi :: class) interface MyImplementation : CoreLibraryApi Library User code
buildList { for (file in this@readFirstLines) { val reader = file.bufferedReader(Charsets.UTF_8) val line = reader.readLine() if (line.isNullOrEmpty()) continue else add(line) } } "Read the first line from each file in the list"
buildList { for (file in this@readFirstLines) { val reader = file.bufferedReader(Charsets.UTF_8) val line = reader.readLine() if (line.isNullOrEmpty()) continue else add(line) } }
buildList { for (file in this@readFirstLines) { val reader = file.bufferedReader(Charsets.UTF_8) val line = reader.readLine() if (line.isNullOrEmpty()) continue else add(line) } }
buildList { for (file in this@readFirstLines) { val reader = file.bufferedReader(Charsets.UTF_8) val line = reader.readLine() if (line.isNullOrEmpty()) continue else add(line) } }
buildList { for (file in this@readFirstLines) { val reader = file.bufferedReader(Charsets.UTF_8) val line = reader.readLine() if (line.isNullOrEmpty()) continue else add(line) } } Realize, that we need to use the resources properly
buildList { for (file in this@readFirstLines) { file.bufferedReader(Charsets.UTF_8).use { reader -> val line = reader.readLine() // this is now a 'continue' inside a lambda if (line.isNullOrEmpty()) continue else add(line) } } }
buildList { for (file in this@readFirstLines) { file.bufferedReader(Charsets.UTF_8).use { reader -> val line = reader.readLine() // this is now a 'continue' inside a lambda if (line.isNullOrEmpty()) continue else add(line) } } }
buildList { for (file in this@readFirstLines) { file.bufferedReader(Charsets.UTF_8).use { reader -> val line = reader.readLine() // this is now a 'continue' inside a lambda if (line.isNullOrEmpty()) continue else add(line) } } } -Xnon-local-break-continue
applyDiscount(order) order is MonthlySubscription -> startSubscription(order) order is OneTimeOrder -> processOrder(order) } val order = getOrder() Guard conditions in when-with-subject expressions
applyDiscount(order) order is MonthlySubscription -> startSubscription(order) order is OneTimeOrder -> processOrder(order) } val order = getOrder() Potentially a logical error Repetition is not nice Guard conditions in when-with-subject expressions
applyDiscount(order) order is YearlySubscription -> processSubscription(order) order is MonthlySubscription -> startSubscription(order) order is OneTimeOrder -> processOrder(order) } val order = getOrder() Guard conditions in when-with-subject expressions
is YearlySubscription -> processSubscription(order) is MonthlySubscription -> startSubscription(order) is OneTimeOrder -> processOrder(order) } val order = getOrder() Guard conditions in when-with-subject expressions
is YearlySubscription -> processSubscription(order) is MonthlySubscription -> startSubscription(order) is OneTimeOrder -> processOrder(order) } val order = getOrder() Error: expecting ' -> ' && Guard conditions in when-with-subject expressions
is YearlySubscription -> processSubscription(order) is MonthlySubscription -> startSubscription(order) is OneTimeOrder -> processOrder(order) } val order = getOrder() if Guard conditions in when-with-subject expressions Guarded conditions: KEEP - 371
is YearlySubscription -> processSubscription(order) is MonthlySubscription -> startSubscription(order) is OneTimeOrder -> processOrder(order) } val order = getOrder() Guard conditions in when-with-subject expressions
> 100 -> applyDiscount(order) is MonthlySubscription -> startSubscription(order) is OneTimeOrder -> processOrder(order) } val order = getOrder() The 'when' branch is never reachable Guard conditions in when-with-subject expressions
is YearlySubscription -> processSubscription(order) is MonthlySubscription -> startSubscription(order) is OneTimeOrder -> processOrder(order) } val order = getOrder() Guard conditions in when-with-subject expressions
class Result object Error: Result() class Success(val value: String): Result() fun <T : Result> render(result: T) = when (result) { Error -> "Error!" is Success -> result.value // Requires no else branch } Required else branch before 2.1
org.jspecify.annotations.*; public class SomeJavaClass { @NonNull public String foo() { ... } @Nullable public String bar() { ... } } Java Kotlin val sjc = SomeJavaClass() sjc.foo().length sjc.bar() ?. length Raises an error in the default strict mode because the result is nullable. To avoid the error, use ?.length instead