传递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直播流可能的未来功能之一。)