相关疑难解决方法(0)

科特林OVERRIDE_BY_INLINE

在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")注释。怎么了?

我已经知道的:

  • 对于普通的内联函数,kotlinc将内联该内联函数的所有用法,但仍会编译该函数的非内联版本,以便可以从Java调用它(并且可能出于向后兼容性或其他原因)。
  • 内联虚拟方法是不可能的。内联只是意味着“将所有代码复制到调用者中”,但是对于调用抽象/接口方法,该实现是在运行时根据所涉及对象的实际类确定的,因此无法知道要复制到哪个实现中功能。

但是,调用最终函数时并非如此。在上面的示例中,当我调用时bar.qux(),编译器可以确保仅使用该特定实现,并且可以安全地内联。它是否覆盖该Foo.qux方法无关紧要-调用foo.qux将使用第1点中提到的非内联版本,并且调用bar.qux可以安全地内联。

只是为了确保开发人员意识到这一警告吗?还是有副作用?

oop inline kotlin

12
推荐指数
1
解决办法
625
查看次数

为什么 Kotlin 中需要显式函数接口修饰符?

考虑用 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 …

kotlin

5
推荐指数
1
解决办法
612
查看次数

无法在使用 Kotlin 的方法调用中为接口传递 lambda(就像 setOnClickListener 那样)

我创建了这个类:

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)

lambda android kotlin

2
推荐指数
1
解决办法
77
查看次数

标签 统计

kotlin ×3

android ×1

inline ×1

lambda ×1

oop ×1