可以用“静态”方式调用扩展函数吗?
是否有可能创建一个扩展函数,并把它称为静态 ?
例如…
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参考文献(扩展函数)中所提到的 ,但这并不意味着它们可以被调用,就好像它们是一个类中的静态函数(在Java中)。
-
我也明白这个代码不会工作,因为没有 System的实例传入编译器会生成的方法; 因此它不会编译。
我为什么要这个?
你们中的一些人可能会想知道为什么这种行为是可取的。 我可以理解为什么你会认为这不是,所以这里有一些原因:
- 它具有标准扩展功能给予的所有好处。
- 不需要创建类的一个实例来访问额外的功能。
- 这些函数可以从系统范围的上下文中访问(只要该类是可见的)。
总结…
Kotlin是否有办法将一个静态函数“钩”到一个类上? 我很想知道。
你真的要求“扩展函数为一个类的引用”或“添加静态方法到现有的类”,这是另一个问题在这里涵盖: 如何添加静态方法到Kotlin的Java类中 ,由功能请求涵盖KT- 11968
扩展函数不能添加到没有实例的任何东西。 对类的引用不是一个实例,因此你不能扩展类似java.lang.System
东西。 但是,您可以扩展现有类的随播对象 。 例如:
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库仅为这种情况添加空的伴侣对象。 其他人不这样做,而那些你是“不幸运的”。 由于Java没有伴随对象,所以对Java也不能这样做。
另一个通常要求的功能是将现有的Java静态方法接受一个类的实例作为第一个参数,并使其表现为扩展功能。 这是通过问题KT-5261 , KT-2844 , KT-732 , KT-3487和其他可能的功能要求来追踪的。
您可以为一个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() }