在 Kotlin 中使用具有函数类型的函数接口
Using functional interfaces with function types in Kotlin
当从 Kotlin 调用 Java 代码时,有 SAM conversion 这样 Java 代码如下:
adapter.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View view, int position) {
// Do stuff here
}
});
可以看起来像这样:
adapter.setOnClickListener { view, position ->
// Do stuff
}
现在,我正在做一个 Kotlin 项目,我想定义一个功能接口作为事件监听器:
interface OnSomeActionListener {
fun onSomeAction(parameter1: Int, parameter2: String)
}
在SomeClass
中我有一个设置监听器的函数:
...
private var onSomeActionListener: OnSomeActionListener? = null
fun setOnSomeActionListener(listener: OnSomeActionListener) {
onSomeActionListener = listener
}
...
当我创建这个 class 的实例并尝试调用 setter 函数时,我是这样做的:
val thing = SomeClass()
thing.setOnSomeActionListener(object : OnSomeActionListener {
override fun onSomeAction(parameter1: Int, parameter2: String) {
// Do stuff here
}
})
我知道 Kotlin 有函数类型,因此不支持来自 this one.
等不同网站的 SAM 转换
我读过一些关于函数类型的内容,但我以前没有使用过它们。
我该如何重写我的代码才能像这样调用 setter 函数?
val thing = SomeClass()
thing.setOnSomeActionListener { parameter1, parameter2 ->
// Do stuff here
}
.
嗯,像这样:
// declare a variable of nullable function type:
var onSomeActionListener: ((Int, String) -> Unit)? = null
// declare higher-order function:
fun setOnSomeActionListener(listener: (Int, String) -> Unit) {
onSomeActionListener = listener
}
// set listener:
val listener: (Int, String) -> Unit = { p1, p2 -> { /* some stuff */ } }
setOnSomeActionListener(listener)
// or in one line:
setOnSomeActionListener { p1, p2 -> { /* some stuff */ } }
函数类型如下所示:
(Parameters) -> ReturnType
在您的情况下,您可以使用 (View, Int) -> Unit
而不是使用接口类型。它看起来像这样:
private var onSomeActionListener: ((View, Int) -> Unit)? = null
fun setOnSomeActionListener(listener: (View, Int) -> Unit) {
onSomeActionListener = listener
}
private fun callSomeActionListener(view: View, position: Int) {
onSomeActionListener?.invoke(view, position)
}
添加姓名
在函数类型中,您还可以为参数指定名称。这在幕后并没有太大变化,但他们可以在此处和调用代码中增加一些清晰度,这很好。
(view: View, position: Int) -> Unit
使用类型别名
为了避免每次都输入(View, Int) -> Unit
,你可以定义一个类型别名:
typealias OnSomeActionListener = (view: View, position: Int) -> Unit
这样您的代码现在又看起来像这样了:
private var onSomeActionListener: OnSomeActionListener? = null
fun setOnSomeActionListener(listener: OnSomeActionListener?) {
onSomeActionListener = listener
}
并调用它:
val thing = SomeClass()
thing.setOnSomeActionListener { view, position ->
// Do stuff here
}
如何定义接受函数和 returns 接口的函数?
fun makeOnSomeActionListener(f: (Int,String) -> Unit) = object : OnSomeActionListener {
override fun onSomeAction(parameter1: Int, parameter2: String) = f(parameter1, parameter2)
}
接口将其工作委托给 f
。
那你可以写
val thing = SomeClass()
thing.setOnSomeActionListener(makeOnSomeActionLisener { parameter1, parameter2 ->
// Do stuff here
})
当从 Kotlin 调用 Java 代码时,有 SAM conversion 这样 Java 代码如下:
adapter.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View view, int position) {
// Do stuff here
}
});
可以看起来像这样:
adapter.setOnClickListener { view, position ->
// Do stuff
}
现在,我正在做一个 Kotlin 项目,我想定义一个功能接口作为事件监听器:
interface OnSomeActionListener {
fun onSomeAction(parameter1: Int, parameter2: String)
}
在SomeClass
中我有一个设置监听器的函数:
...
private var onSomeActionListener: OnSomeActionListener? = null
fun setOnSomeActionListener(listener: OnSomeActionListener) {
onSomeActionListener = listener
}
...
当我创建这个 class 的实例并尝试调用 setter 函数时,我是这样做的:
val thing = SomeClass()
thing.setOnSomeActionListener(object : OnSomeActionListener {
override fun onSomeAction(parameter1: Int, parameter2: String) {
// Do stuff here
}
})
我知道 Kotlin 有函数类型,因此不支持来自 this one.
等不同网站的 SAM 转换我读过一些关于函数类型的内容,但我以前没有使用过它们。
我该如何重写我的代码才能像这样调用 setter 函数?
val thing = SomeClass()
thing.setOnSomeActionListener { parameter1, parameter2 ->
// Do stuff here
}
.
嗯,像这样:
// declare a variable of nullable function type:
var onSomeActionListener: ((Int, String) -> Unit)? = null
// declare higher-order function:
fun setOnSomeActionListener(listener: (Int, String) -> Unit) {
onSomeActionListener = listener
}
// set listener:
val listener: (Int, String) -> Unit = { p1, p2 -> { /* some stuff */ } }
setOnSomeActionListener(listener)
// or in one line:
setOnSomeActionListener { p1, p2 -> { /* some stuff */ } }
函数类型如下所示:
(Parameters) -> ReturnType
在您的情况下,您可以使用 (View, Int) -> Unit
而不是使用接口类型。它看起来像这样:
private var onSomeActionListener: ((View, Int) -> Unit)? = null
fun setOnSomeActionListener(listener: (View, Int) -> Unit) {
onSomeActionListener = listener
}
private fun callSomeActionListener(view: View, position: Int) {
onSomeActionListener?.invoke(view, position)
}
添加姓名
在函数类型中,您还可以为参数指定名称。这在幕后并没有太大变化,但他们可以在此处和调用代码中增加一些清晰度,这很好。
(view: View, position: Int) -> Unit
使用类型别名
为了避免每次都输入(View, Int) -> Unit
,你可以定义一个类型别名:
typealias OnSomeActionListener = (view: View, position: Int) -> Unit
这样您的代码现在又看起来像这样了:
private var onSomeActionListener: OnSomeActionListener? = null
fun setOnSomeActionListener(listener: OnSomeActionListener?) {
onSomeActionListener = listener
}
并调用它:
val thing = SomeClass()
thing.setOnSomeActionListener { view, position ->
// Do stuff here
}
如何定义接受函数和 returns 接口的函数?
fun makeOnSomeActionListener(f: (Int,String) -> Unit) = object : OnSomeActionListener {
override fun onSomeAction(parameter1: Int, parameter2: String) = f(parameter1, parameter2)
}
接口将其工作委托给 f
。
那你可以写
val thing = SomeClass()
thing.setOnSomeActionListener(makeOnSomeActionLisener { parameter1, parameter2 ->
// Do stuff here
})