Im very new in Kotlin and must be miss something, so please show me workaround.
I create a class for store any available listener types (static methods, interfaces, class members and lambdas) in one place. It work but I have one annoying problem: Kotlin cant automatically find right overloaded function for lambda functions.
Here is head part of implementation:
class Event<in LT : Any>(listenerEventMethod : LT.(CallSource) -> Unit) {
fun call(Source : CallSource) {}
fun <T : Any> add(eventUser : T, listenerObject : LT) {}
fun <T : Any, S : CallSource> add(eventUser : T, closureMethod : T.(src : S) -> Unit) {}
fun <T : Any, S : CallSource> add(eventUser : T, functionMethod : (src : S) -> Unit) {}
fun <T : Any, S : CallSource> addF(eventUser : T, functionMethod : (src : S) -> Unit) {}
}
Implementation doesnt matter, the problem is in usage of Event.add
function.
If I try to use one of overloaded functions “add” Kotlin cannot choose which to use and I forced to create special function “addF” for use with lambdas.
Its very annoying because lambdas are must usable type of listeners.
Is where any problems with my code or its just impossible to use single add
for all types?
Note: Its works fine for anonymous functions, problem only with lambdas. Its strange, both has exactly the same type.
Here is test case with problem and Kotlin error diagnostics.
interface CallSource
class Test : CallSource {
//test interface used by listeners
interface TCall {
fun call(src : CallSource) {}
}
//event holder for type: (CallSource)->Unit
val OnChange = Event(TCall::call)
//notify all attached listeners
fun F() { OnChange.call(this) }
}
//class which set listeners
class TestUserVoid(val t : Test) {
//TEST entry
fun F() {
//add listener as anon function
val v = { it : Test ->
println("lambdaVAR: $it")
}
t.OnChange.add(this, v)
//add listener as lambda
/* PROBLEM:
Error:(149, 16) Kotlin: Cannot choose among the following candidates without completing type inference:
public final fun <T : Any, S : CallSource> add(eventUser: TestUserVoid, functionMethod: (src: Test) -> Unit): EventBase defined in jm.test.ktest.Event
public final fun <T : Any, S : CallSource> add(eventUser: TestUserVoid, closureMethod: TestUserVoid.(src: Test) -> Unit): EventBase defined in jm.test.ktest.Event
t.OnChange.add(this) { it : Test ->
println("lambdaINL: $it")
}
*/
//forced to use non-overloaded function to set lambda listener
t.OnChange.addF(this) { it : Test ->
println("lambdaF: $it")
}
//emulate call listeners
t.F()
}
}
fun main(args : Array<String>) {
val t = Test()
TestUserVoid(t).F()
}