为什么Kotlin不能推断下面的lambda参数(在Java – > Kotlin转换之后)?

我有以下的Java代码:

public class DatabaseManager { public interface Predicate<T> { boolean test(T t); } private interface Consumer<T> { void apply(T t); } private void updateLiveLists() { updateLiveLists(liveList -> true); } private void updateLiveLists(Predicate<MutableLiveList<?>> predicate) { forEachLiveList(liveList -> { if (predicate.test(liveList)) { refresh(liveList); } }); } private void forEachLiveList(Consumer<MutableLiveList<?>> consumer) { ... } 

然后我在Android Studio中使用Java -> Kotlin conversion

 class DatabaseManager { interface Predicate<T> { fun test(t: T): Boolean } private interface Consumer<T> { fun apply(t: T) } private fun updateLiveLists(predicate: Predicate<MutableLiveList<*>> = { liveList -> true }) { forEachLiveList({ liveList -> if (predicate.test(liveList)) { refresh(liveList) } }) } private fun forEachLiveList(consumer: Consumer<MutableLiveList<*>>) { ... } 

失败,出现以下错误:

类型不匹配

Required: DatabaseManager.Consumer<MutableLiveList<*>>

发现:(???) – >单位

现在我不得不将代码更改为以下内容:

 private fun updateLiveLists(predicate: Predicate<MutableLiveList<*>> = object : Predicate<MutableLiveList<*>> { override fun test(t: MutableLiveList<*>): Boolean { return true; } }) { forEachLiveList(object : DatabaseManager.Consumer<MutableLiveList<*>> { // <--- !! override fun apply(t: MutableLiveList<*>) { if (predicate.test(t)) { refresh(t) } } }) } 

好的,所以我不得不明确地声明这个匿名接口是一个明确的object子类,因为Kotlin无法找出lambda。


如果有帮助,我在下面的函数中发生同样的问题:

 fun refresh(vararg tables: Table) { updateLiveLists({ liveList -> for (table in tables) { if (liveList.getTable() === table) { return@updateLiveLists true } } false }) } 

其中说:

类型不匹配:

Required: DatabaseManager.Predicate<MutableLiveList<*>>

发现:??? – >布尔值

而我必须这样做

 fun refresh(vararg tables: Table) { updateLiveLists(object: DatabaseManager.Predicate<MutableLiveList<*>> { // <-- override fun test(t: MutableLiveList<*>): Boolean { for (table in tables) { if (t.getTable() === table) { return true } } return false } }) } 

为什么,我怎样才能避免这种情况? 如何在没有Kotlin的情况下使用我自己的谓词/消费者对lambda类型感到困惑?

感谢/u/lupajz我现在知道问题是在Kotlin中定义的接口没有被SAM转换,因为https://discuss.kotlinlang.org/t/kotlin-and-sam-interface-with-two α参数/5分之293

基本上归结为

“当你可以使用Kotlin的函数接口和类型别名时,你为什么要这样做;如果你需要这个,那么在Java中定义接口”。


有几个解决方法:

1.)内联对象(这是我在上面作为问题的一部分展示的)

2.)输入别名+暴露重载的方法

 private typealias KotlinPredicate<T> = (T) -> Boolean; private typealias KotlinConsumer<T> = (T) -> Unit; class DatabaseManager { private interface Consumer<T> { fun apply(t : T) : Unit; } private fun forEachLiveList(consumer: Consumer<MutableLiveList<*>>) { forEachLiveList({ consumer.apply(it) }) } private fun forEachLiveList(consumer: KotlinConsumer<MutableLiveList<*>>) { ... } 

 interface Predicate<T> { fun test(t : T) : Boolean; } fun updateLiveLists(predicate: Predicate<MutableLiveList<*>>) { updateLiveLists({ predicate.test(it) }) } fun updateLiveLists(predicate: KotlinPredicate<MutableLiveList<*>> = { liveList -> true }) { forEachLiveList({ liveList -> if (predicate.invoke(liveList)) { refresh(liveList) } }) }