Kotlin中高阶函数和SAM转换的奇怪行为

时间:2018-06-05 13:48:33

标签: java android functional-programming kotlin higher-order-functions

这个问题与我之前的问题有关:Modifying an anonymous function to invoke another anonymous function in Kotlin

我写了一个函数来修改答案中给出的点击监听器:

fun modifiedClick( onClick: (View) -> Unit): (View) -> Unit {
        return {
            //hide keyboard and invoke click only if there is a gap between frequent clicks
            hideKeyBoard(it)
            if (!isClickDisabled) {
                onClick(it)
            }
        }
    }

现在,如果我将其称为如下:

view.setOnClickListener {modifiedClick { login() }}

它不会调用login()

但如果我将SAM转换更改为正常,如下所示:

view.setOnClickListener (modifiedClick { login() })

有效!

另外,如果我内联函数如下:

inline fun modifiedClick(crossline onClick: (View) -> Unit): (View) -> Unit {
            return {
                //hide keyboard and invoke click only if there is a gap between frequent clicks
                hideKeyBoard(it)
                if (!isClickDisabled) {
                    onClick(it)
                }
            }
        }

并打电话如下:

view.setOnClickListener {modifiedClick { login() }}

它甚至没有调用modifiedClick

将其更改为

view.setOnClickListener (modifiedClick { login() })

正在调用modifiedClick()login()函数。

有谁能帮我理解发生了什么?

1 个答案:

答案 0 :(得分:1)

view.setOnClickListener {modifiedClick { login() }}

在这里你写了一个简写(我用它来解释类型/函数名称):

view.setOnClickListener(object : OnClickListener() {
    override fun onClick(e: ClickEvent) {
        modifiedClick { login() }
    }
})

它是一个监听器,在单击时,会调用您的modifiedClick方法,该方法会创建并返回已修改的侦听器。它返回的监听器被忽略,没有可观察到的效果。

与此相反,当你写

view.setOnClickListener(modifiedClick { login() })

您只需致电modifiedClick { login() }并将其返回值传递给setOnClickListener - 这就是您想要做的事情。