如何从定义它们的类外部调用扩展方法? [英] How do I call extension methods from outside the class they are defined in?
问题描述
这是一个演示问题的最小示例:
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做到这一点. String
和Base
似乎都没有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
成员扩展中的调度接收者.它将与任何其他将功能类型与接收器一起使用的功能一起使用:apply
,run
,use
等.
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屋!