传递lambda代替接口

我创建了一个界面:

interface ProgressListener { fun transferred(bytesUploaded: Long) } 

但可以只用作匿名类,而不是lambda

 dataManager.createAndSubmitSendIt(title, message, object : ProgressListener { override fun transferred(bytesUploaded: Long) { System.out.println(bytesUploaded.toString()) } }) 

我认为这应该是一个可能性,以lambda取代它:

 dataManager.createAndSubmitSendIt(title, message, {System.out.println(it.toString())}) 

但是我得到错误:类型不匹配; 需要 – ProgressListener,找到 – () – >单位?

我究竟做错了什么?

正如@ zsmb13所说,SAM转换只支持Java接口。

你可以创建一个扩展函数来使它工作:

 // Assuming the type of dataManager is DataManager. fun DataManager.createAndSubmitSendIt(title: String, message: String, progressListener: (Long) -> Unit) { createAndSubmitSendIt(title, message, object : ProgressListener { override fun transferred(bytesUploaded: Long) { progressListener(bytesUploaded) } }) } 

Kotlin仅支持Java接口的SAM转换。

注意这个特性只适用于Java interop; 由于Kotlin具有适当的函数类型,函数自动转换为Kotlin接口的实现是不必要的,因此不受支持。

– 官方文件

如果你想在参数中使用一个lambda表达式,使你的函数取一个函数参数而不是一个接口。 (至少现在,支持Kotlin接口的SAM转换是一个持续的讨论,这是Kotlin 1.1直播流可能的未来功能之一。)