简体   繁体   中英

Conditional nullable return type in kotlin

I wrote some code and that work!

    public fun toTimeStamp(epoch: Long?): String? = when (epoch) {
        null -> null
        else -> toTimeStamp(epoch)
    }

    public fun toTimeStamp(epoch: Long): String = 
        TIMESTAMP_PATTERN.print(toGregorianDateTime(epoch))

but when i converted it to extention function dosent work. compiler say method name is duplicated.

I need somthing like this :

fun Long?.toDate() : String? {
// some code
}

fun Long.toDate() : String {
// some code
}

or is there annotation to say if input parameter is null return type is null too ?

By the looks of it, your objective can be accomplished with safe calls. Say you had this function:

fun Long.toDate(): String =
    TIMESTAMP_PATTERN.print(toGregorianDateTime(epoch))

You can use it on a nullable long like so:

myNullableLong?.toDate()

That will return null if the long is null, and the correct date otherwise.

The problem is that you'll have to think about how this looks in the JVM when using kotlin for the JVM. Your methods:

fun Long?.toDate() : String? {
   // some code
 }

fun Long.toDate() : String {
   // some code
}

Are equivalent in Java to:

public static @Nullable String toDate(@Nullable Long receiver) {}

public static @NonNull String toDate(long receiver) {}

Unfortunately, in Java annotations do nothing to resolve ambiguity of declarations (neither return types), so essentially these methods are the same and that's why the compiler complains.

Like some already mentioned, you most likely can just use safe calls.

Declare an extension on Long and whenever this long can be null, just call ?.toDate on it. Just like @llama Boy suggested.

This will achieve what you want:

  1. When input is nullable, output will be nullable too
  2. When input is not nullable, output will be not nullable too.

You can avoid the problem by using @JvmName annotation on one of them :

@JvmName("toDateNullable")
fun Long?.toDate() : String? {
// some code
}

fun Long.toDate() : String {
// some code
}

but I agree with the other answers that in most cases you can prefer just using safe calls instead of defining a separate Long?.toDate .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM