我如何从定义类的外部调用扩展方法?

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

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调用扩展方法是微不足道的:

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

但我不知道如何在纯Kotlin中做到这一点。 StringBase都没有extension方法。

首先请注意,定义为成员的扩展函数需要两个接收者,一个是封闭类的实例( 调度接收者 ,通常是封闭类的实例),另一个是函数扩展类型的实例( 扩展接收者 )。 这是在这里记录 。

所以,要从课堂外调用这样一个功能,你必须提供两个接收器。 Kotlin 没有像(x, "abc").stringExtension()那样显式的语法 , (x, "abc").stringExtension() ,但是你可以使用一个扩展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

在你的情况下,这将是with(o) { "hello world".extension('l') }

正如@KirillRakhman所指出的那样, C的扩展函数的扩展接收者也可以被隐式地用作C定义的扩展的调度接收者:

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

您的扩展功能仅在Base / Derived类中定义。 请参阅将扩展声明为成员 。

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

为了在类之外使用扩展方法,你不应该在类中实现它,你应该这样做:

 package com.sample.test import java.io.File fun File.folderLength() : Long { return 0L } 

所以在你的类中调用这个方法:

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

希望这应该可以帮到你。