单个抽象成员不能声明默认值

问题描述 投票:0回答:1

我按照 SonarLint 建议将一些只有一个函数的接口转换为 SAM,但由于函数参数中有默认值而出现问题。

fun interface HomeListener {

   fun setSubTitle(subtitle: String = DEFAULT_VALUE_STRING)

}

我想知道这里出了什么问题,或者这是 Kotlin 和 JVM 之间的限制? JetBrain 的问题追踪中已经有一个 Bug 报告,但自 2021 年以来没有更新?

kotlin jvm single-abstract-method
1个回答
0
投票

按照我的理解,SAM的要点是,如果只有一个要实现的抽象方法,你可以只提供一个 lambda 让编译器使用它作为实现。通常,您请求对象的实现,而“用户”需要提供它,并且可以选择仅提供 lambda 来实现。这对应于直接 lambda 参数:

fun doStuff(onSubtitleChange: (String) -> Unit) {
    ...
    onSubtitleChange("foo")
    ...
}

这意味着在您的情况下,

setSubTitle
并不意味着由“用户”调用,而是由您调用,因此它不需要外部接口。就像使用 lambda 参数一样,您不会这样做(这当然是错误的语法):

fun doStuff(onSubtitleChange: (String = DEFAULT_VALUE_STRING) -> Unit) {
    ...
    if (processedString != null)
        onSubtitleChange(processedString)
    else
        onSubtitleChange()
    ...
}

但是你会这样做,这样会更清晰、更有意义:

fun doStuff(onSubtitleChange: (String) -> Unit) {
    ...
    onSubtitleChange(processedString ?: DEFAULT_VALUE_STRING)
    ...
}

所以在我看来,拥有默认参数是没有意义的。而是像这样提供它:

fun doStuff(listener: HomeListener) {
    ...
    listener.setSubtitle(processedString ?: DEFAULT_VALUE_STRING)
    ...
}
© www.soinside.com 2019 - 2024. All rights reserved.