Skip to content

Instantly share code, notes, and snippets.

@marcellogalhardo
Last active February 19, 2022 16:42
Show Gist options
  • Save marcellogalhardo/0a6fce186598185f440d4a1ffd7d1dea to your computer and use it in GitHub Desktop.
Save marcellogalhardo/0a6fce186598185f440d4a1ffd7d1dea to your computer and use it in GitHub Desktop.
The missing guard clauses for Kotlin. A simple and elegant way to guard against invariants.
/**
* Invokes [otherwise] if the [value] is false.
*/
@OptIn(ExperimentalContracts::class)
inline fun guard(value: Boolean, otherwise: () -> Unit) {
contract {
returns() implies value
}
if (!value) otherwise()
}
/**
* Invokes [otherwise] if the [value] is null, or returns the not null [value].
*/
@OptIn(ExperimentalContracts::class)
inline fun <T : Any> guardNotNull(value: T?, otherwise: () -> T): T {
contract {
returns() implies (value != null)
}
return value ?: otherwise()
}
var num: Int? = null
// Example with Guard
fun printStateWithNum1(state: String) {
val notNullNum = guardNotNull(num) { return }
guardNotNull(state) { return }
guard(state.isNotBlank()) { return }
guard(state.all { it.isLetterOrDigit() }) { return }
println("$state:$notNullNum")
}
// Example without Guard
fun printWithNum2(state: String) {
val notNullNum = num ?: return
if (state != null) return
if (state.isNotBlank()) return
if (state.all { it.isLetterOrDigit() }) return
println("$state:$notNullNum")
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment