Kotlin - 如何使用相同的param类型重载函数,但是一个可以为空

时间:2018-05-23 10:10:07

标签: kotlin

我正在尝试向Android中的Calendar类添加两个扩展功能,以将特定日期模式转换为日历,反之亦然

fun Calendar.fromIsoString(date: String): Calendar = this.apply {
    time = SimpleDateFormat(SERVER_DATE_PATTERN, Locale.US).parse(date)
}

fun Calendar.fromIsoString(date: String?): Calendar? {
    if (date == null) return null
    time = SimpleDateFormat(SERVER_DATE_PATTERN, Locale.US).parse(date)
    return this
}

但是它给了我以下错误:

  

平台声明冲突:以下声明具有相同的JVM签名(fromIsoString(Ljava / util / Calendar; Ljava / lang / String;)Ljava / util / Calendar;)

是否可以将这两个功能放在一起?如何?

注意: 我以某种方式通过向其中一个函数添加Unit可选参数来解决问题:

fun Calendar.fromIsoString(date: String?, a: Unit = Unit): Calendar? {
if (date == null) return null
    time = SimpleDateFormat(SERVER_DATE_PATTERN, Locale.US).parse(date)
    return this
}

但我认为这很棘手而且不是一个好习惯! 有没有更好的办法?

1 个答案:

答案 0 :(得分:4)

有一个简单的解决方案,允许您在不更改方法或要从Kotlin调用它们的名称的情况下执行此操作。

对于Kotlin来说,两种方法之间的区别是明确的,但对于JVM来说却并非如此。因此,告诉Kotlin你想要一个不会影响Kotlin代码的方法的其他内部JVM名称。只有Java代码才会看到替代名称。例如:

fun Calendar.fromIsoString(date: String): Calendar = this.apply {
    // ... your code without change
}

@JvmName("fromIsoStringNullable") // <-- this solves your problem without changing the name in Kotlin
fun Calendar.fromIsoString(date: String?): Calendar? {
    // ... your code without change
}

瞧!没有更多错误!您可以使用相同名称someCalendar.fromIsoString(...)

从Kotlin调用任一版本

其他答案和评论表明可空性是语法糖是远非正确的。这些类型被写入字节码作为额外的元数据,只有Kotlin才能看到和执行。但除此之外,它还为参数添加了@Nullable注释。事实上,所有Kotlin生成的函数参数在字节码中都有@NotNull@Nullable注释,供​​其他语言或分析人员查看和执行,如果他们足够关心的话。