Home > Mobile >  In Kotlin, how can I bind an extension method to work within a receiver scope function
In Kotlin, how can I bind an extension method to work within a receiver scope function

Time:10-20

This feels like some kind of inconsistency because it works with a standalone function, but not with a class/interface method:

class TestClass {
    val foo = "bar"
}

fun testScope(scope: TestClass.() -> Any) {

    val test = TestClass()

    scope(test)

}


// this works
fun TestClass.standaloneRunInTest() {
    println(foo)
}

interface Example {
    
    val name: String

    // but this doesn't?
    fun TestClass.interfaceRunInTest() {
        println(foo   name)
    }

    object Instance: Example {
        override val name: String = "Baz"
    }

}


fun main() {

    testScope {
        standaloneRunInTest() // prints "bar"
        Example.Instance.interfaceRunInTest() // expected to print "barbaz", but gets Unresolved reference: interfaceRunInTest
    }

}

More likely though I am doing something silly!

CodePudding user response:

Example.Instance is not an instance of TestClass. You're using syntax as if you're trying to call interfaceRunInTest() as a function of Example.Instance, which won't work.

To call an extension function that is defined in the scope of a type, you have to bring both types into scope as receivers, for example:

testScope {
    Example.Instance.run { interfaceRunInTest() }
}

// or 
Example.Instance.run {
    testScope {
        interfaceRunInTest()
    }
}

The run and with scope functions are useful for this purpose.

  • Related