How do I call extension methods from outside the class they are defined in?

感情迁移 提交于 2019-11-28 13:32:14
hotkey

First, note that an extension function defined as a member requires two receivers, one is an instance of the enclosing class (dispatch receiver, usually this of the enclosing class) and the other is the instance of the type that the function extends (extension receiver). This is documented here.

So, to call such a function from outside the class you have to provide two receivers. Kotlin doesn't have any syntax to do that explicitly like (x, "abc").stringExtension(), but you can provide the dispatch receiver implicitly using an extension lambda:

class C(val name: String) {
    fun String.extended() = this + " extended by " + name
}

fun main(args: Array<String>) {
    val c = C("c")
    with(c) { println("abc".extended()) }
}

(runnable demo of this code)

In the with(...) { ... } block, c becomes the implicit receiver, thus allowing you to use it as a dispatch receiver in C member extensions. This would work with any other function that uses functional types with receivers: apply, run, use etc.

In your case, it would be with(o) { "hello world".extension('l') }

As @KirillRakhman noted, an extension receiver of an extension function for C can also be implicitly used as a dispatch receiver for the extensions defined inside C:

fun C.someExtension() = "something".extended()

To decale an extension method outside the class using it, you should NOT implement it inside a class, and you should do like this:

package com.sample.test

import java.io.File

fun File.folderLength() : Long {
    return 0L
}

So in your class that call this method:

package com.sample.util

import com.sample.test.*
import java.io.File

class foo{
    fun getFolderSize(url: String) : Long{
        var file = new File("...")
        var length = file.folderLength()
        return length
    }
}

Hope this should help you.

Your extension function is defined only inside of Base/Derived class. See Declaring Extensions as Members.

abstract class Base {
    abstract fun String.extension(x: Char)
}

class Derived : Base() {
    override fun String.extension(x: Char) {
        // Calling lots of methods on String, hence extension method
        println("${first()} $length ${last()} ${firstOrNull { it == x }} ...")
    }

    fun callExtension(c: Char) {
        "hello".extension(c)
    }
}

fun main(args: Array<String>) {
    val base = Derived()
    base.callExtension('h')
}
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!