可以用“静态”方式调用扩展函数吗?

是否有可能创建一个扩展函数,并把它称为静态

例如…

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的实例传入编译器会生成的方法; 因此它不会编译。

我为什么要这个?

你们中的一些人可能会想知道为什么这种行为是可取的。 我可以理解为什么你会认为这不是,所以这里有一些原因:

  1. 它具有标准扩展功能给予的所有好处。
  2. 不需要创建类的一个实例来访问额外的功能。
  3. 这些函数可以从系统范围的上下文中访问(只要该类是可见的)。

总结…

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