如何从定义它们的类外部调用扩展方法? [英] How do I call extension methods from outside the class they are defined in?

查看:61
本文介绍了如何从定义它们的类外部调用扩展方法?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这是一个演示问题的最小示例:

Here is a minimal example that demonstrates the problem:

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 }} ...")
    }
}

从Java调用扩展方法很简单:

Calling the extension method from Java is trivial:

Base o = new Derived();
o.extension("hello world", 'l');

但是我不知道怎么用纯Kotlin做到这一点. StringBase似乎都没有extension方法.

But I can't figure out how to do it in pure Kotlin. Neither String nor Base seems to have the extension method.

推荐答案

首先,请注意,定义为成员的扩展功能需要两个接收者,一个是封闭类的实例( dispatch接收器 ,通常是封闭类的this),另一个是函数扩展类型的实例(扩展接收器).在此处中对此进行了记录.

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.

因此,要从类外部调用此类函数,必须提供两个接收器. Kotlin 没有任何语法可以像(x, "abc").stringExtension()那样明确地执行此操作,但是您可以使用扩展lambda :<

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()) }
}

(此代码的可运行演示)

with(...) { ... } 块中,c成为隐式接收者,因此允许您将其用作C成员扩展中的调度接收者.它将与任何其他将功能类型与接收器一起使用的功能一起使用:applyrunuse等.

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.

您的情况应该是with(o) { "hello world".extension('l') }

@KirillRakhman 所述,也可以隐式使用C扩展功能的扩展接收器.作为C中定义的扩展的派发接收器:

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()

这篇关于如何从定义它们的类外部调用扩展方法?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆