What would be a more elegant way to rewrite the below code in kotlin.
if (xList.isEmpty()) {
throw SomeException("xList was empty")
}
Do we have a throwif operator or something?
What would be a more elegant way to rewrite the below code in kotlin.
if (xList.isEmpty()) {
throw SomeException("xList was empty")
}
Do we have a throwif operator or something?
I like to use the takeIf standard function to validate, with elvis operator addition, it gives this:
xList.takeIf { it.isNotEmpty() } ?: throw SomeException("xList was empty")
I have to add that in most cases an IllegalArgumentException is what I need, and it is simpler to just use require.
In cases that we need an IllegalStateException, we can rather use check.
See also: checkNotNull, requireNotNull, error
Yet another suggestion, terse and not requiring additional code :
xList.isNotEmpty() || throw SomeException("xList was empty")
It works because throw is an expression, having the type Nothing which is a subtype of everything, including Boolean.
In Kotlin library, there are functions which throw exception if the input is invalid, e.g.
requireNotNull(T?, () -> Any). You can refer to these functions and write a similar function to handle empty list if you want.
public inline fun <T> requireNotEmpty(value: List<T>?, lazyMessage: () -> Any): List<T> {
if (value == null || value.isEmpty()) {
val message = lazyMessage()
throw IllegalArgumentException(message.toString())
} else {
return value
}
}
//Usage:
requireNotEmpty(xList) { "xList was empty" }
Or simply use require(Boolean, () -> Any):
require(!xList.isEmpty()) { "xList was empty" }
I don't know of a function in the standard library, but you can easily do this yourself:
/**
* Generic function, evaluates [thr] and throws the exception returned by it only if [condition] is true
*/
inline fun throwIf(condition: Boolean, thr: () -> Throwable) {
if(condition) {
throw thr()
}
}
/**
* Throws [IllegalArgumentException] if this list is empty, otherwise returns this list.
*/
fun <T> List<T>.requireNotEmpty(message: String = "List was empty"): List<T> {
throwIf(this.isEmpty()) { IllegalArgumentException(message) }
return this
}
// Usage
fun main(args: Array<String>) {
val list: List<Int> = TODO()
list.filter { it > 3 }
.requireNotEmpty()
.forEach(::println)
}
The original code is compact, transparent and flexible.
An extension fun with fixed exception may be more compact.
infix fun String.throwIf(b: Boolean) {
if (b) throw SomeException(this)
}
"xList was empty" throwIf xList.isEmpty()