尝试传递需要SAM接口的方法时,无法使用lambdas进行编译 [英] Using lambdas does not compile when trying to pass in a method expecting a SAM interface
问题描述
我想了解lambda和Kotlin.我创建了这个简单的例子
I am trying to understand lambdas and Kotlin. I created this trivial example
interface OnClickListener {
fun onClick(s: String)
}
class Button {
var clickListener: OnClickListener? = null
fun setOnClickListener(listener: OnClickListener?) {
clickListener = listener
}
fun click() {
clickListener?.onClick("hello")
}
}
fun main(args: Array<String>) {
val b = Button()
b.setOnClickListener(
object : OnClickListener {
override fun onClick(s: String) {
println(s)
}
}
)
/*
Variation 1
val l = {
s -> println(s)
}
b.clickListener = l*/
/*
Variation 2
b.setOnClickListener{
s -> println(s)
}
*/
/*
Variation 3
b.clickListener = {
s -> println(s)
}
*/
b.click()
}
因此,仅当我传递匿名对象时,以上代码才会编译.但我想弄清楚如何使用lambda.
使用lambda编译的3个变体都没有.
我认为,由于OnClickListener
是SAM,所以我应该可以轻松传递lambda
我在这里做什么错了?
So the above code only compiles if I pass an anonymous object. But I wanted to figure out how to use the lambdas.
None of the 3 variation to use a lambda compiles.
I thought since the OnClickListener
is a SAM I should easily be able to pass in a lambda
What am I doing wrong here?
推荐答案
要使用lambda,您需要使用Java接口.
To be able to use a lambda, you need to use a Java interface.
首先,创建一个Java文件并创建一个接口:
First, create a Java file and create an interface:
public interface OnClickListener {
void onClick(String s);
}
然后在您的main
中:
b.setOnClickListener(OnClickListener { s ->
println(s)
})
关于您的Button
类:
class Button {
var clickListener: OnClickListener? = null //You can use this too but there's another way as well.
//lateinit var clickListener: OnClickListener //Telling the compiler that you will initialize it later on.
fun setOnClickListener(listener: OnClickListener) { //removed redundant ? from the function signature.
clickListener = listener
}
fun click() {
clickListener?.onClick("hello") //Incase of lateinit, you don't need a '?' anymore
}
}
SAM转换仅在Java代码和Kotlin代码之间起作用.
SAM conversion only works between a Java code and a Kotlin code.
编辑:由于在Kotlin中,您也可以将函数存储在变量中,这是我的另外两分钱,以另一种方式来实现它:
Since in Kotlin, you can store a function in a variable as well, here is my another two cents on how you can do it in a different way:
class Button {
lateinit var myFunction: (String) -> Unit
fun setOnClickListener(block : (String) -> Unit) {
myFunction = block //storing state of your 'listener'
}
fun onClick() = myFunction.invoke("Invoked from onClick function")
}
然后在您的main
中:
fun main() {
val button = Button()
button.setOnClickListener { s ->
println(s)
}
button.onClick()
}
这篇关于尝试传递需要SAM接口的方法时,无法使用lambdas进行编译的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!