Function interface in Kotlin 1.4

左心房为你撑大大i 提交于 2020-01-04 06:13:05

问题


This feature will be coming Kotlin 1.4. Here is an excerpt from KotlinConf'19.

fun interface Action {
    fun run()
}

fun runAction(a: Action) = a.run()

runAction{
    println("Hello")
}

It looks nice, but I still don't know what it does.

What is the function interface? What is its practical value? What specific scenarios can it be used for?


回答1:


This is about functional interfaces — interfaces with a Single Abstract Method (also called SAM interfaces).

To understand the point, I'll need to cover a little history…  In Java, lambdas were added relatively recently.  Before that, you implemented callbacks and similar by implementing a suitable interface.  For example, if you wanted to be informed when an AWT component was actioned, you'd create an object which implemented the ActionListener interface.  That has a single method (called actionPerformed()); you'd put your code inside that method:

myButton.addActionListener(new ActionListener() {
    public void actionPerformed(ActionEvent e) {
        // Do something
    }
});

When they added lambdas, they wanted to blend in with all the existing code, and change as little as possible, so they did it exactly the same way: the compiler infers which interface you're implementing, and creates an object implementing that interface.  You could write:

myButton.addActionListener(e -> {
    // Do something
});

which is shorter — but it compiles down to pretty much the same as the first example.

So in Java, functions are not first-class objects; lambdas are simply a more concise way to implement functional interfaces.

In Kotlin, however, functions are first-class objects: you can write a lambda (or an anonymous function) on its own, assign it, pass it to functions, return it from functions, and so on — so there's no need for SAM interfaces at all!

For easier interoperability with Java, Kotlin lets you easily implement Java SAM interfaces, in the same way you do from Java:

myButton.addActionListener {
    // Do something
}

But Kotlin <= 1.3 doesn't let you implement Kotlin interfaces that way; you need to implement those explicitly.  (I suspect this was partly to encourage developers to use proper functions, with all their other advantages, and not rely on the Java-style workaround.)

Your example illustrates this.  It has an interface (Action) with one abstract method (run()).  It has a function (runAction()) which takes an instance of that interface.  And it has some code which wants to call that function, passing just the code for the run() method.

In Kotlin <= 1.3, you'd have to do the latter explicitly, e.g.:

runAction(object : Action {
    override fun run() {
        println("Hello")
    }
})

But from Kotlin 1.4, you can mark the interface as fun interface, and use the Java-style shortcut, as in your example.

(You may or may not think this is a good thing…)




回答2:


It meant to support lambda

I wanted to have the invoke-function with functional interfaces is because that is the way java defines lambda’s and lambda’s should be invokable

To create lambda in kotlin instead of Java

SAM conversions currently only work for Java interfaces and abstract classes. The initial idea behind this design was to use function types explicitly for such use-cases. It turned out, however, that function types and typealiases don’t cover all the use-cases, and people often had to keep an interface in Java only to get a SAM-conversion for it.



来源:https://stackoverflow.com/questions/59442419/function-interface-in-kotlin-1-4

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!