I want to create a function like ifEmpty() of Kotlin that will also check for null:
ifNullOrEmpty{
//some code if null or empty
}
How can i do this?
And does anyone know what the code below is called?
: R where C : CharSequence, C : R
Example of Kotlin ifEmpty() function.
@SinceKotlin("1.3")
@kotlin.internal.InlineOnly
public inline fun <C, R> C.ifEmpty(defaultValue: () -> R): R where C : CharSequence, C : R =
if (isEmpty()) defaultValue() else this
Thanks and have a nice day!
CodePudding user response:
does anyone know what the code below is called?
You are mixing 2 pieces in your snippet:
: R
is simply the return type of the functionwhere C : CharSequence, C : R
is called awhere
clause. Its purpose is to specify multiple upper bounds on the type parameters of the function.
How can i do this?
Regarding the implementation itself, you may not be able to use as many generics as the original ifEmpty
(due to @InlineOnly
being internal), but you can do a simpler version if this is enough for you:
inline fun <R : CharSequence> R?.ifNullOrEmpty(defaultValue: () -> R): R =
if (isNullOrEmpty()) defaultValue() else this
The difference with the stdlib's ifEmpty
is that the lambda in this case cannot widen the type (you can't return a CharSequence
from the lambda if you called ifNullOrEmpty
on a String
), but this should rarely be needed.
CodePudding user response:
As explained in other answers, you can't create ifNullOrEmpty()
with similar generic logic as in ifNull()
, because you need @InlineOnly
which is currently internal and can be used by stdlib only.
If you don't mind using internal components and writing code that is potentially not forward-compatible, you can utilize a small hack:
@Suppress("INVISIBLE_REFERENCE", "INVISIBLE_MEMBER")
@kotlin.internal.InlineOnly
public inline fun <C, R> C.ifNullOrEmpty(defaultValue: () -> R): R where C : CharSequence, C : R =
if (isNullOrEmpty()) defaultValue() else this
Alternatively, you can use "less generic" implementation as provided by @Joffrey, which should be sufficient for most use cases.
CodePudding user response:
Honestly I don't fully understand why the generic types are necessary in the original ifEmpty
but I think you can just do it like this:
inline fun CharSequence?.ifNullOrEmpty(defaultValue: () -> CharSequence): CharSequence =
if (isNullOrEmpty()) defaultValue() else this