扩展函数可以用"static"的方式调用吗?
Can extension functions be called in a "static" way?
是否可以创建一个扩展函数并像静态函数一样调用它?
例如...
fun System.sayByeAndExit() {
println("Goodbye!")
System.exit()
}
fun main(args: Array<String>) {
System.sayByeAndExit() // I'd like to be able to call this
}
我知道代码示例不起作用...
我了解到 kotlin 的扩展函数是静态解析的,如Kotlin Reference (Extension Functions)中所述,但这并不意味着它们可以像 class 中的静态函数一样被调用(在 Java 意义上)。
我也明白这段代码不会工作,因为没有 System 的实例 可以传递给编译器将生成的方法;因此它不会编译。
我为什么要这个?
有些人可能想知道为什么需要这种行为。我能理解为什么你会认为那不是,所以这里有一些原因:
- 它具有标准扩展函数的所有优点。
- 不需要创建 class 的实例 只需 即可访问额外的功能。
- 可以从应用程序范围的上下文访问函数(前提是class可见)。
总结一下...
Kotlin 有办法将静态函数 "hook" 放到 class 上吗? 我很想知道。
您可以为 object
定义扩展函数并从系统范围的上下文中使用它。一个对象只会被创建一次。
object MyClz
fun MyClz.exit() = System.exit(0)
fun main(args: Array<String>) {
MyClz.exit()
}
或
class MyClz {
companion object
}
fun MyClz.Companion.exit() = System.exit(0)
fun main(args: Array<String>) {
MyClz.exit()
}
你真的是在问 "extension functions for a Class reference" 或 "adding static methods to existing classes",这里有另一个问题: which is covered by a feature request KT-11968
扩展函数不能添加到没有实例的任何东西。对 Class 的引用不是一个实例,因此你不能扩展像 java.lang.System
这样的东西。但是,您可以 extend a companion object 现有 class。例如:
class LibraryThing {
companion object { /* ... */ }
}
允许您扩展 LibraryThing.Companion
并因此调用一些新的 myExtension()
方法看起来您正在扩展 Class 引用本身,而实际上您正在扩展伴随对象:
fun LibraryThing.Companion.myExtension() = "foo"
LibraryThing.Companion.myExtension() // results in "foo"
LibraryThing.myExtension() // results in "foo"
因此,您可能会发现一些 Kotlin 库专门针对这种情况添加了空的伴随对象。其他人没有,对于那些你是 "out of luck." 因为 Java 没有伴随对象,你也不能对 Java 做同样的事情。
另一个通常要求的功能是采用现有的 Java 静态方法,该方法接受 class 的实例作为第一个参数,并使其表现为扩展函数。这是由问题 KT-5261, KT-2844, KT-732, KT-3487 和可能的其他功能请求跟踪的。
是否可以创建一个扩展函数并像静态函数一样调用它?
例如...
fun System.sayByeAndExit() {
println("Goodbye!")
System.exit()
}
fun main(args: Array<String>) {
System.sayByeAndExit() // I'd like to be able to call this
}
我知道代码示例不起作用...
我了解到 kotlin 的扩展函数是静态解析的,如Kotlin Reference (Extension Functions)中所述,但这并不意味着它们可以像 class 中的静态函数一样被调用(在 Java 意义上)。
我也明白这段代码不会工作,因为没有 System 的实例 可以传递给编译器将生成的方法;因此它不会编译。
我为什么要这个?
有些人可能想知道为什么需要这种行为。我能理解为什么你会认为那不是,所以这里有一些原因:
- 它具有标准扩展函数的所有优点。
- 不需要创建 class 的实例 只需 即可访问额外的功能。
- 可以从应用程序范围的上下文访问函数(前提是class可见)。
总结一下...
Kotlin 有办法将静态函数 "hook" 放到 class 上吗? 我很想知道。
您可以为 object
定义扩展函数并从系统范围的上下文中使用它。一个对象只会被创建一次。
object MyClz
fun MyClz.exit() = System.exit(0)
fun main(args: Array<String>) {
MyClz.exit()
}
或
class MyClz {
companion object
}
fun MyClz.Companion.exit() = System.exit(0)
fun main(args: Array<String>) {
MyClz.exit()
}
你真的是在问 "extension functions for a Class reference" 或 "adding static methods to existing classes",这里有另一个问题:
扩展函数不能添加到没有实例的任何东西。对 Class 的引用不是一个实例,因此你不能扩展像 java.lang.System
这样的东西。但是,您可以 extend a companion object 现有 class。例如:
class LibraryThing {
companion object { /* ... */ }
}
允许您扩展 LibraryThing.Companion
并因此调用一些新的 myExtension()
方法看起来您正在扩展 Class 引用本身,而实际上您正在扩展伴随对象:
fun LibraryThing.Companion.myExtension() = "foo"
LibraryThing.Companion.myExtension() // results in "foo"
LibraryThing.myExtension() // results in "foo"
因此,您可能会发现一些 Kotlin 库专门针对这种情况添加了空的伴随对象。其他人没有,对于那些你是 "out of luck." 因为 Java 没有伴随对象,你也不能对 Java 做同样的事情。
另一个通常要求的功能是采用现有的 Java 静态方法,该方法接受 class 的实例作为第一个参数,并使其表现为扩展函数。这是由问题 KT-5261, KT-2844, KT-732, KT-3487 和可能的其他功能请求跟踪的。