我正在尝试在Kotlin中开发一种简单的信号/插槽系统。这是我到目前为止的内容:
open class Signal<T : Function<Unit>>() {
val callbacks = mutableListOf<T>()
open fun addCallback(slot: T) {
callbacks.add(slot)
}
open fun emit(vararg params: Any) {
for(call in callbacks) {
call(*params)
}
}
}
fun test(myarg: Int) = println(myarg)
fun main(args: Array<String>) {
val myevent = Signal<(Int) -> Unit>()
myevent.addCallback(::test)
myevent.emit(2)
}
一个想法是创建一个Signal
的实例以及一个通用模板,以规定哪些参数用于回调。然后可以将回调添加到Signal
中。最后,每当需要Signal
...好...“已信号”时,就使用emit
方法。如有必要,此方法会将所有参数传递给相应的回调。
问题是此代码导致以下错误:
kotlin\Signal.kt:30:4: error: expression 'call' of type 'T' cannot be invoked as a function. The function 'invoke()' is not found
有问题的行是:
call(*params)
关于如何从这里处理事情的任何建议?
答案 0 :(得分:1)
实际上具有invoke
运算符的各种函数类型都被here一一定义为Function0
,Function1
等。
我认为您无法创建一个Signal
实现,该实现可能具有带有任意数量和任何类型的参数的回调。也许只用一个参数进行回调就可以解决吗?
open class Signal<T> {
val callbacks = mutableListOf<(T) -> Unit>()
open fun addCallback(slot: (T) -> Unit) {
callbacks.add(slot)
}
open fun emit(param: T) {
for (call in callbacks) {
call(param)
}
}
}
fun test(myarg: Int) = println(myarg)
fun main(args: Array<String>) {
val myevent = Signal<Int>()
myevent.addCallback(::test)
myevent.emit(2)
}
(请注意,您可以将(T) -> Unit
的两种用法都替换为Function1<T, Unit>
。)