我遵循SonarLint的建议,将一些只有一个函数的接口转换为SAM,但由于函数参数中有默认值而出现问题。
fun interface HomeListener { fun setSubTitle(subtitle: String = DEFAULT_VALUE_STRING) }
字符串我想知道这里的问题是什么,或者这是Kotlin和JVM之间的限制?在JetBrain的问题跟踪器中已经有一个bug report,但自2021年以来没有更新?
mbjcgjjk1#
根据我的理解,SAM的要点是,如果只有一个抽象方法要实现,你可以只提供一个lambda,让编译器使用它作为实现。通常是你用实现请求对象,而“用户”需要提供它,可以选择只提供一个lambda。这相当于一个直接的lambda参数:
fun doStuff(onSubtitleChange: (String) -> Unit) { ... onSubtitleChange("foo") ... }
字符串这意味着setSubTitle在你的例子中不是由“用户”调用,而是由你调用,所以它不需要一个向外的接口。就像lambda参数一样,你不会这样做(当然这是错误的语法):
setSubTitle
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) ... }
型
1条答案
按热度按时间mbjcgjjk1#
根据我的理解,SAM的要点是,如果只有一个抽象方法要实现,你可以只提供一个lambda,让编译器使用它作为实现。通常是你用实现请求对象,而“用户”需要提供它,可以选择只提供一个lambda。这相当于一个直接的lambda参数:
字符串
这意味着
setSubTitle
在你的例子中不是由“用户”调用,而是由你调用,所以它不需要一个向外的接口。就像lambda参数一样,你不会这样做(当然这是错误的语法):型
但是你会这样做,这更清楚,更有意义:
型
因此,在我看来,有一个默认参数是没有意义的。不如这样提供它:
型