在Kotlin中使用inline功能实现接口时:
interface Foo {
fun qux(fn: () -> Unit)
}
open class Bar : Foo {
final override inline fun qux(fn: () -> Unit){TODO()}
}
Run Code Online (Sandbox Code Playgroud)
IDE(可能还有编译器)抱怨以下消息:
Override by an inline function
Run Code Online (Sandbox Code Playgroud)
要取消显示此消息,我必须使用@Suppress("OVERRIDE_BY_INLINE")注释。怎么了?
我已经知道的:
但是,调用最终函数时并非如此。在上面的示例中,当我调用时bar.qux(),编译器可以确保仅使用该特定实现,并且可以安全地内联。它是否覆盖该Foo.qux方法无关紧要-调用foo.qux将使用第1点中提到的非内联版本,并且调用bar.qux可以安全地内联。
只是为了确保开发人员意识到这一警告吗?还是有副作用?
考虑用 Java 定义的 SAM
public interface Transform {
public String apply(String str);
}
Run Code Online (Sandbox Code Playgroud)
该接口自动支持 Kotlin 中的 lambda 到类型转换
fun run(transform: Transform) {
println(transform.apply("world"))
}
run { x -> "Hello $x!!" } // runs fine without any issues
Run Code Online (Sandbox Code Playgroud)
但现在考虑一个 Kotlin 接口
interface Transform2 {
fun apply(str: String): String
}
Run Code Online (Sandbox Code Playgroud)
现在调用 run 函数的唯一方法是创建 Transform2 的匿名实例
run(object : Transform2 {
override fun transform(str: String): String = "hello $str!!"
})
Run Code Online (Sandbox Code Playgroud)
但如果我们将 Transform2 接口设为函数式接口,则以下情况是可能的
run { str -> "hello $str!!" }
Run Code Online (Sandbox Code Playgroud)
为什么 Kotlin 编译器无法自动将 lambda …
我创建了这个类:
class SomeClass {
var listener: SomeListener? = null
interface SomeListener {
fun onClick(v: View?)
}
fun addSomeListener(l: SomeListener){
listener = l
}
}
Run Code Online (Sandbox Code Playgroud)
我按如下方式调用它,效果很好:
SomeClass().addSomeListener(object : SomeClass.SomeListener {
override fun onClick(v: View?) {
// Do something
}
})
Run Code Online (Sandbox Code Playgroud)
但是,以下语法在 Android Studio 中失败:
SomeClass().addSomeListener{ view ->
// Do something
}
Run Code Online (Sandbox Code Playgroud)
类型不匹配。必需: SomeClass.SomeListener 找到: () ? 单元
我不明白这个,因为Android的setOnClickListener方法是用同样的方式实现的:
/**
* Register a callback to be invoked when this view is clicked. If this view is not
* …Run Code Online (Sandbox Code Playgroud)