I had the following Java code:
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) {
...
}
Then I used Java -> Kotlin conversion
in Android Studio:
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<*>>) {
...
}
Fails with the following error:
Type mismatch
Required: DatabaseManager.Consumer<MutableLiveList<*>>
Found: (???) -> Unit
Now I had to change code to following:
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)
}
}
})
}
Okay, so I had to explicitly declare this anonymous interface as an explicit subclass of object
, as for whatever reason Kotlin couldn't figure out the lambda.
If it helps, I have the same problem occurring in a function below it:
fun refresh(vararg tables: Table) {
updateLiveLists({ liveList ->
for (table in tables) {
if (liveList.getTable() === table) {
return@updateLiveLists true
}
}
false
})
}
Which says:
Type Mismatch:
Required: DatabaseManager.Predicate<MutableLiveList<*>>
Found: ??? -> Boolean
And I have to do this instead
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
}
})
}
Why, and how can I avoid this? How can I use my own Predicate/Consumer without Kotlin getting confused about the lambda type?
object :
as I did above, or change these interfaces totypealias
of Kotlin's function types, or use Kotlin's function types directly? Changing totypealias
or to Kotlin types would work only if I change all code that uses this to Kotlin as well. Hrmm... Yes, that is a very relevant question. – EpicPandaForce