首页 文章

在Kotlin中使用功能类型的功能接口

提问于
浏览
6

从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
    }

    ...

当我创建这个类的实例并尝试调用setter函数时,我这样做:

val thing = SomeClass()

thing.setOnSomeActionListener(object : OnSomeActionListener {
    override fun onSomeAction(parameter1: Int, parameter2: String) {
        // Do stuff here
    }
})

我'm aware that Kotlin has function types therefore doesn' t支持来自各个站点的SAM转换,例如this one .

我已经阅读了一些关于函数类型的内容,但我之前没有使用它们 .

How would I rewrite my code so that I can invoke the setter function like this?

val thing = SomeClass()

thing.setOnSomeActionListener { parameter1, parameter2 ->
    // Do stuff here
}

.

3 回答

  • 0

    函数类型如下所示:

    (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)
    }
    

    Add names

    在函数类型中,您还可以指定参数的名称 . 这并没有太大的改变,但它们可以在这里和调用代码中添加一些清晰度,这很好 .

    (view: View, position: Int) -> Unit
    

    Using a type alias

    为避免每次都输入 (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
    }
    
  • 11

    嗯,这样的事情:

    // 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 */ } }
    

    欲了解更多信息:Higher-Order Functions and Lambdas

  • 0

    如何定义接受函数并返回接口的函数?

    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
    })
    

相关问题