Skip to content

Instantly share code, notes, and snippets.

@Takhion
Last active July 28, 2021 19:19
Show Gist options
  • Save Takhion/fd0f3c04706414689f54a85a5255f241 to your computer and use it in GitHub Desktop.
Save Takhion/fd0f3c04706414689f54a85a5255f241 to your computer and use it in GitHub Desktop.
Exhaustive `when` mapping in Kotlin
@file:Suppress("PackageDirectoryMismatch") // root package looks great when importing, ie. `import exhaustive`
/**
* Allows requiring an exhaustive mapping in a `when` block when used with the [rangeTo] operator.
* @sample [exhaustive_when_example]
*/
@Suppress("ClassName") // lowercase because it should look like a keyword
object exhaustive {
/** @see [exhaustive] */
@JvmStatic @Suppress("NOTHING_TO_INLINE") // static & inline so Proguard can remove it while optimizing
inline operator fun <T> rangeTo(whenBlock: T): T = whenBlock
}
private enum class SomeEnum { a, b, c }
private fun exhaustive_when_example(enum: SomeEnum) {
exhaustive..when (enum) {
SomeEnum.a -> Unit
SomeEnum.b -> println()
SomeEnum.c -> readLine()
}
}
@Jswizzy
Copy link

Jswizzy commented Mar 22, 2019

This way of doing it is much faster val <T> T.exhaustive: T get() = this

@Takhion
Copy link
Author

Takhion commented May 27, 2019

@Jswizzy: This way of doing it is much faster val <T> T.exhaustive: T get() = this

The main issue with that approach is that it pollutes the global namespace, making the extension appear on every type, which can be very confusing/misleading. In addition, the exhaustive keyword should really be placed as close as possible to the when, instead of at the end of a (potentially long) block.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment