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

byx*_*xor 5 kotlin extension-function

是否可以创建一个扩展函数并将其称为静态

例如...

fun System.sayByeAndExit() {
    println("Goodbye!")
    System.exit()
}

fun main(args: Array<String>) {
    System.sayByeAndExit() // I'd like to be able to call this
}
Run Code Online (Sandbox Code Playgroud)

我知道代码示例不起作用......

  • 我理解kotlin的扩展函数是静态解析的,Kotlin Reference(扩展函数)中所述,但这并不意味着它们可以被调用,就好像它们是类中的静态函数(在Java意义上).

  • 我也明白这个代码不起作用,因为没有 System的实例传递给编译器将生成的方法; 因此它不会编译.

我为什么要这个?

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

  1. 它具有标准扩展功能带来的所有好处.
  2. 不需要 仅为访问额外功能而创建类的实例.
  3. 可以从系统范围的上下文访问这些函数(前提是该类是可见的).

总结一下......

Kotlin有办法将静态函数"挂钩"到类中吗?我很想知道.

Jay*_*ard 9

你真的要求"类引用的扩展函数"或"向现有类添加静态方法",这里有另一个问题:如何在Kotlin中为Java类添加静态方法,这些方法由特征请求KT覆盖 - 11968

扩展功能无法添加到没有实例的任何内容中.对类的引用不是实例,因此您无法扩展类似的内容java.lang.System.但是,您可以扩展现有类的伴随对象.例如:

class LibraryThing {
    companion object { /* ... */ }
}
Run Code Online (Sandbox Code Playgroud)

允许您扩展LibraryThing.Companion,因此myExtension()当您正在扩展伴随对象的单例实例时,调用某些新方法看起来就像是在扩展Class引用本身:

fun LibraryThing.Companion.myExtension() = "foo"

LibraryThing.Companion.myExtension() // results in "foo"
LibraryThing.myExtension() // results in "foo"
Run Code Online (Sandbox Code Playgroud)

因此,您可能会发现一些Kotlin库仅为此情况添加空的伴随对象.其他人则没有,对于那些你"运气不好"的人.由于Java没有伴随对象,因此您也无法对Java执行相同操作.

另一个常见的功能是采用现有的Java静态方法,该方法接受类的实例作为第一个参数,并使其表现为扩展函数.这可以通过问题KT-5261,KT-2844,KT-732,KT-3487以及可能的其他功能请求进行跟踪.