可以在"静态"中调用扩展函数。方法是什么?

时间:2016-09-03 18:30:06

标签: 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
}

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

  • 我了解kotlin的扩展功能静态解析Kotlin Reference (Extension Functions) 中所述,但这并不意味着他们可以被称为它们是类中的静态函数(在Java意义上)。

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

为什么我要这个?

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

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

    Kotlin是否有办法实现&#34; hook&#34;一个类的静态函数?我很想知道。

2 个答案:

答案 0 :(得分:9)

你真的要求&#34;扩展函数用于类引用&#34;或者&#34;向现有类添加静态方法&#34;这里有另一个问题:How can one add static methods to Java classes in Kotlin,其中包含功能请求KT-11968

扩展功能无法添加到没有实例的任何内容中。对类的引用不是实例,因此您无法扩展java.lang.System之类的内容。但是,你可以extend a companion object现有的课程。例如:

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库仅为此案例添加了空伴随对象。其他人则没有,对于那些你运气不好的人。&#34;由于Java没有伴随对象,因此您也无法对Java执行相同的操作。

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

答案 1 :(得分:1)

您可以为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()
}