OVERRIDE_BY_INLINE in Kotlin

前端 未结 1 1081
孤城傲影
孤城傲影 2021-02-12 11:21

When implementing an interface in Kotlin with an inline function:

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

open class Bar : Foo {
    final         


        
相关标签:
1条回答
  • 2021-02-12 12:00

    I know this is pretty late, but here's why. You got this right:

    It is impossible to inline a virtual method.

    But you should consider that, while Bar.foo is not virtual in the sense that it could be overridden (it can't be), it is virtual in the sense that a decision can be made to run it at runtime. Consider the following example which builds on your own:

    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
    }
    

    Here, Bar.qux is invoked initially, but Baz.qux is invoked the second time. So, not every call can be inlined. So why is this a warning and not a compiler error, like when we declare an open fun with the inline modifier? Consider the following:

    val bar: Bar = Bar()
    bar.qux { }
    

    In this case, the compiler can safely inline all calls to qux on the variable bar because it's declared as a Bar. Even if the class is open as in your example, since the method itself is final, any derived type will always use exactly that qux. So this statement,

    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.

    is true only when the compiler statically knows the type of bar to be an actual Bar. It's an error when it's open because none of them can be inlined which definitely isn't the desired behavior, it's a warning when it's an override because only some of them can be inlined, which might not be the desired behavior.

    This example is available at play.kotlinlang.org

    0 讨论(0)
提交回复
热议问题