Kotlin generics change return type


#1

I have this method in Java I want to convert to Kotlin, but still use from both Java and Kotlin:

@Nullable
public static <T extends CharSequence> T nullIfEmpty(@Nullable final T t) {
   return TextUtils.isEmpty(t) ? null : t;
}

In another place I have a method that accepts Strings:

public static doSomething(@Nullable String foo) {}

Which I call in this way:

String foo = "   ";
doSomething(nullIfEmpty(foo)); // == doSomething(null); since foo is empty

After I converted the nullIfEmpty() to this Kotlin snippet:

fun <T : CharSequence> nullIfEmpty(t: T?): T? {
    return if (TextUtils.isEmpty(t)) null else t
}

Java no longer compiles complaining that there is an argument type mismatch - calling the function with a CharSequence when it expects a String.

What would be the correct syntax to fix this?

P.S. This is a cross-posting from stackoverflow for visibility:


#2

I reworked your code to make it more idiomatic Kotlin and this works for me:

fun <T : CharSequence?> T.nullIfEmpty() = takeUnless { it.isNullOrBlank() }

Note that in Kotlin, this version would be used as:

foo.nullIfEmpty()

But in Kotlin code, I think it would be more readable spelling it out without the utility function as in one of the following:

 foo?.takeUnless{ it.isBlank() }
 foo?.takeIf{ it.isNotBlank() }
 foo.takeUnless{ it.isNullOrBlank() }

If foo itself were not nullable then you can drop the first ? as in:

 foo.takeUnless{ it.isBlank() }
 foo.takeIf{ it.isNotBlank() }