Kotlin 1.4中的功能接口 [英] Function interface in Kotlin 1.4
问题描述
此功能将在Kotlin 1.4
中推出.这是KotlinConf'19
的摘录.
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?
推荐答案
这是关于功能接口的内容-具有单一抽象方法的接口(也称为SAM接口).
This is about functional interfaces — interfaces with a Single Abstract Method (also called SAM interfaces).
要理解这一点,我需要介绍一些历史记录……在Java中,lambdas是最近才添加的.在此之前,您通过实现合适的接口来实现回调等.例如,如果希望在操作AWT组件时收到通知,则可以创建一个实现ActionListener
接口的对象.那有一个单一的方法(称为actionPerformed()
);您可以将代码放入该方法中:
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
}
});
当他们添加lambda时,他们希望与所有现有代码融合在一起,并进行尽可能少的更改,因此它们的操作方式完全相同:编译器推断您正在实现的接口,并创建一个实现对象该界面.您可以这样写:
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.
因此,在Java中,函数不是一等对象. lambda只是实现功能接口的一种更简洁的方法.
So in Java, functions are not first-class objects; lambdas are simply a more concise way to implement functional interfaces.
但是在Kotlin中,函数是的一类对象:您可以自己编写lambda(或匿名函数),进行分配,将其传递给函数,从函数中返回,依此类推-完全不需要SAM接口!
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!
为了更轻松地与Java互操作,Kotlin使您可以轻松地实现Java SAM接口,就像在Java中一样:
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
}
但是Kotlin< = 1.3不允许您以这种方式实现Kotlin接口;您需要明确实现这些功能. (我怀疑这部分是在鼓励开发人员使用适当的功能以及其他所有优点,而不是依靠Java风格的变通方法.)
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.)
您的示例对此进行了说明.它具有一个接口(Action
)和一个抽象方法(run()
).它具有一个使用该接口实例的函数(runAction()
).而且它有一些想要调用该函数的代码,只传递run()
方法的代码.
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.
在Kotlin< = 1.3中,您必须明确地执行后者,例如:
In Kotlin <= 1.3, you'd have to do the latter explicitly, e.g.:
runAction(object : Action {
override fun run() {
println("Hello")
}
})
但是从Kotlin 1.4开始,您可以将接口标记为fun interface
,并使用Java样式的快捷方式,如示例所示.
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…)
这篇关于Kotlin 1.4中的功能接口的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!