将函数调用转换为Lambda(SAM)

在一个android程序中,我有以下代码:

clockCheckBox.setOnClickListener((object: View.OnClickListener { override fun onClick(view: View): Unit { if (clockCheckBox.isChecked()) enableClocks() else disableClocks() } })) 

在Android Studio中,出现了一个工具提示,

这个检查报告了一个匿名对象文字实现一个单一抽象方法的java接口,可以转换成lambda表达式调用。

我试图做到这一点,但我得到的只是语法错误。 你能告诉我正确的语法吗? 我也许应该解释一下,这段代码是在我的activity的onCreate方法中,clockCheckBox是一个局部变量

 val clockCheckBox = findViewById(R.id.clockCheckBox) as CheckBox 

上面的代码可以简化如下:

 // v--- parentheses is unnecessary setOnClickListener { // v--- boolean property parenthess is unnecessary if (clockCheckBox.isChecked) enableClocks() else disableClocks() } 

您可以进一步看到Java互操作性 。

转换它的方法是只留下接口名称和函数内的代码。 一个图片(在这种情况下的例子)胜过千言万语,这就是它的样子:

 clockCheckBox.setOnClickListener(View.OnClickListener { if (clockCheckBox.isChecked()) enableClocks() else disableClocks() }) 

您可以在kotlin文档页面上阅读更多信息。

在了解Kotlin公约的同时仔细观察检查报告是有用的。

这个检查报告一个匿名的对象文字实现一个java接口与单一的抽象方法 (重点矿井) ,可以转换成lambda表达式调用。

本报告中的关键之一是“用一种抽象方法实现一个java接口”。 这是关键,因为实现这些类型接口的匿名对象可以简单地写成lambda表达式。 换句话说,您可以跳过匿名对象文本和接口的名称,只使用符合单个抽象方法签名的lambda表达式。

在onClick的情况下,等效签名是

  (view: View) -> Unit 

所以你的例子lambda是

 { view -> if (clockCheckBox.isChecked) enableClocks() else disableClocks() } 

但是既然你没有在你的lambda体中使用'view',那么可以省略'view – >'。 而不是视图,你正在使用clockCheckBox(这是在拉姆达封闭视图)。

最后,当函数调用的最后一个参数是lambda时,而不是写入

 myFun( { ... } ) 

你可以改为写

 myFun { ... } 

换句话说,你正在移动括号外的最后一个参数lambda(如果只有一个参数,括号可以省略)。 所以你完整的例子使用lambda将是

 clockCheckBox.setOnClickListener { if(clockCheckBox.isChecked()) enableClocks() else disableClocks() }