2017-07-19 93 views
0

在Android程序中,我有以下代码:转换函数调用拉姆达(SAM)

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

在Android Studio中,工具提示出现,说,

此检验报告的匿名对象字面值,实现一个带抽象方法的 java接口,该接口可以转换为带有lambda表达式的 调用。

我试过这样做,但我得到的只是语法错误。你能告诉我正确的语法吗?也许我应该解释一下,这个代码是在我的活动onCreate方法和clockCheckBox是定义为

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

回答

2

上述代码可以如下简化:

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

可以进一步看到Java Interoperability

1

将其转换为只留下接口名称和功能中的代码的方式局部变量。一张图片(例如,在这种情况下)是胜过千言万语所以这是怎么会是这样的:

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

你可以阅读更多关于它的kotlin docs page

2

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

该检查报告一个匿名对象字面实现与一个抽象方法(重点煤矿)可被转化成具有λ表达式调用Java接口。

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

在onclick的情况下,相当于签名

(view: View) -> Unit 

因此,对于您的示例拉姆达是

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

但因为你是不是在你的拉姆达机身采用“视图” ,'view - >'可以省略。而不是视图,你正在使用clockCheckBox(这是一个关闭lambda中的视图)。

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

myFun({ ... }) 

你可以代替写

myFun { ... } 

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

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