Kotlin With and TakeIf
with runs a block with a value as the receiver, and takeIf keeps a value only when a test passes. A failed takeIf test gives null.
with returns a block value
The crate is the receiver of the block. The block returns twice the item count.
class Crate(val name: String, val items: Int)
fun main() {
val crate = Crate("books", 9)
val doubled = with(crate) {
println(name)
items * 2
}
println(doubled)
}takeIf passing and failing
The first age passes the test and stays. The second age fails the test and becomes null.
fun main() {
val adult = 20.takeIf {
it >= 18
}
println(adult)
val child = 12.takeIf {
it >= 18
}
println(child)
}takeUnless keeps on failure
takeUnless drops a score when the test passes. A low score is dropped, and a high score stays.
fun main() {
val low = 45.takeUnless {
it < 50
}
println(low)
val high = 80.takeUnless {
it < 50
}
println(high)
}takeIf with the Elvis operator
An empty name fails the test, so the Elvis operator supplies a fallback. A real name passes and stays.
fun main() {
val name = "".takeIf {
it.length > 0
} ?: "guest"
println(name)
val city = "Oslo".takeIf {
it.length > 0
} ?: "unknown"
println(city)
}Example
class Account(val owner: String, val balance: Int)
fun main() {
val account = Account("Mira", 120)
val label = with(account) {
"$owner has $balance"
}
println(label)
val large = account.balance.takeIf {
it >= 100
} ?: 0
println(large)
}Key points
- with takes the receiver as its first argument.
- Inside a with block, members of the receiver are read directly.
- with returns the value of the last expression in its block.
- takeIf returns the value when its test passes.
- takeIf returns null when its test fails.
- takeUnless is the mirror of takeIf, and it keeps the value when its test fails.
In this example, with reads the owner and the balance of the account to build a label. takeIf keeps the balance because it reaches 100. The Elvis fallback of 0 is not needed.
Note
The Elvis operator can replace a null from takeIf with a fallback value.
Try it Yourself
Edit the code, then press Run.
Running is simulated ยท Kotlin Playground
Exercise
What does 12.takeIf { it >= 18 } give?