gpt4 book ai didi

oop - Kotlin 中的 OVERRIDE_BY_INLINE

转载 作者:行者123 更新时间:2023-12-02 11:43:26 26 4
gpt4 key购买 nike

在 Kotlin 中使用 inline 实现接口(interface)时功能:

interface Foo {
fun qux(fn: () -> Unit)
}

open class Bar : Foo {
final override inline fun qux(fn: () -> Unit){TODO()}
}

IDE(可能还有编译器)提示此消息:
Override by an inline function

要禁止显示此消息,我必须使用 @Suppress("OVERRIDE_BY_INLINE")注解。怎么了?

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

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

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

    最佳答案

    我知道这已经很晚了,但这就是原因。你做对了:

    It is impossible to inline a virtual method.



    但是你应该考虑到这一点,而 Bar.foo它不是虚拟的,因为它可以被覆盖(它不能被覆盖),它是虚拟的,因为它可以决定在运行时运行它。考虑以下基于您自己构建的示例:
    interface Foo {
    fun qux(fn: () -> Unit)
    }

    open class Bar : Foo {
    final override inline fun qux(fn: () -> Unit){TODO()}
    }

    class Baz : Foo {
    override fun qux(fn: () -> Unit) = TODO()
    }

    fun main() {
    var foo: Foo = Bar()
    foo.qux { } // calls Bar.qux
    foo = Baz()
    foo.qux { } // calls Foo.qux
    }

    在这里, Bar.qux最初被调用,但 Baz.qux被第二次调用。因此,并非每个调用都可以内联。那么为什么这是一个警告而不是编译器错误,比如当我们声明 open fun 时与 inline修饰符?考虑以下:
    val bar: Bar = Bar()
    bar.qux { }

    在这种情况下,编译器可以安全地内联对 qux 的所有调用。在变量 bar 上因为它被声明为 Bar .即使类在您的示例中是打开的,因为方法本身是 final , 任何派生类型将始终使用 qux .所以这个说法,

    In the example above, when I invoke bar.qux(), the compiler can ensure that only this particular implementation will be used, and can safely inlined.



    仅当编译器静态知道 bar 的类型时才为真做一个真正的 Bar .为 open 时为错误因为它们都不能被内联,这绝对不是所需的行为,当它是一个覆盖时它是一个警告,因为只有其中一些可以被内联,这可能不是所需的行为。

    This example is available at play.kotlinlang.org

    关于oop - Kotlin 中的 OVERRIDE_BY_INLINE,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53188558/

    26 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com