尝试传递需要SAM接口的方法时,无法使用lambdas进行编译 [英] Using lambdas does not compile when trying to pass in a method expecting a SAM interface

查看:96
本文介绍了尝试传递需要SAM接口的方法时,无法使用lambdas进行编译的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想了解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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆