如何在 Kotlin 中将对象表达式转换为 lambda?

How to convert a object expression to lambda in Kotlin?

我是 Android 开发的新手。最近我正在学习 Kotlin,我正在尝试弄清楚 setOnClickListener。但是,我在使用Kotlin将对象表达式转换为lambda的过程中遇到了问题

步骤 1. Java 中的 setOnClickListener:

buttonLogin.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                // my code
            }
        });

第 2 步。然后我使用对象表达式将 Java 代码转换为 Kotlin 代码:

buttonLogin.setOnClickListener(object : View.OnClickListener {
            override fun onClick(p0: View?) {
                // my code
            }
        })

第 3 步。然后 IntelliJ 提示我将对象表达式转换为 lambda:

buttonLogin.setOnClickListener {
        // my code
    }

看起来比较简洁,但是我看不懂第3步背后的逻辑。 于是上网查了一些资料,上面写着

Any function that receives an interface with a single function can be substituted by a lambda

它在 setOnClickListener 上执行。 但是我还是不能完全理解,所以我定义了一个接口,class来验证一下。

这是我的代码:

interface MyInterface {
    fun method1()
}

class MyClass {
    fun method2(myInterface: MyInterface) {
        myInterface.method1()
    }
}

fun main() {
    val myClass = MyClass()
    myClass.method2(object : MyInterface {
        override fun method1() {
            println("Hello, world.")
        }
    })
    
    // So how to write the lambda to replace object expression?
}

第 3 步中的代码称为尾随 lambdas

根据Kotlin约定,如果函数的最后一个参数是一个函数,那么作为对应参数传递的lambda表达式可以放在括号外,

如果 lambda 是该调用中的唯一参数,则可以完全省略括号:

例如:

fun function(f : (String) -> Unit) {

}

fun main() {
    function {
        
    }
}

查看此功能的 Kotlin 文档

https://kotlinlang.org/docs/lambdas.html#passing-trailing-lambdas

您可以转换代码以使用此功能

class MyClass {
    fun method2(function: () -> Unit) {
        function()
    }
}

fun main() {
    val myClass = MyClass()
    myClass.method2 {
        println("Hello, world.")
    }

    // Or you can store the lambda in variable and use it like tihs
    val myClass2 = MyClass()
    val function = {
        println("Hello, world.")
    }
    myClass2.method2(function)

}

或者只是将您的界面转换为功能界面

fun interface MyInterface {
    fun method1()
}

class MyClass {
    fun method2(myInterface: MyInterface) {
        myInterface.method1()
    }
}

fun main() {
    val myClass = MyClass()
    myClass.method2 { 
        println("Hello, world.") 
    }
}