如何从它们定义的 class 外部调用扩展方法?
How do I call extension methods from outside the class they are defined in?
这是一个演示问题的最小示例:
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 中做到这一点。 String
和 Base
似乎都没有 extension
方法。
您的扩展函数仅在 Base/Derived class 内部定义。参见 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')
}
首先注意定义为成员的扩展函数需要两个receiver,一个是封闭class的实例(dispatch receiver,通常this
是封闭的 class),另一个是函数扩展类型的实例 (extension receiver)。这已记录在案 here。
因此,要从 class 外部调用此类函数,您必须提供两个接收器。科特林 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
等
在你的情况下,它将是 with(o) { "hello world".extension('l') }
如 @KirillRakhman 所述,C
的扩展函数的扩展接收器也可以隐式用作 C
中定义的扩展的调度接收器:
fun C.someExtension() = "something".extended()
要在 class 之外使用扩展方法,你应该 不 在 class 中实现它,你应该这样做:
package com.sample.test
import java.io.File
fun File.folderLength() : Long {
return 0L
}
所以在你的 class 中调用这个方法:
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
}
}
希望这对您有所帮助。
这是一个演示问题的最小示例:
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 中做到这一点。 String
和 Base
似乎都没有 extension
方法。
您的扩展函数仅在 Base/Derived class 内部定义。参见 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')
}
首先注意定义为成员的扩展函数需要两个receiver,一个是封闭class的实例(dispatch receiver,通常this
是封闭的 class),另一个是函数扩展类型的实例 (extension receiver)。这已记录在案 here。
因此,要从 class 外部调用此类函数,您必须提供两个接收器。科特林 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
等
在你的情况下,它将是 with(o) { "hello world".extension('l') }
如 @KirillRakhman 所述,C
的扩展函数的扩展接收器也可以隐式用作 C
中定义的扩展的调度接收器:
fun C.someExtension() = "something".extended()
要在 class 之外使用扩展方法,你应该 不 在 class 中实现它,你应该这样做:
package com.sample.test
import java.io.File
fun File.folderLength() : Long {
return 0L
}
所以在你的 class 中调用这个方法:
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
}
}
希望这对您有所帮助。