如何解析 Signal/Slot 系统的函数模板泛型?

How to Resolve Function Template Generics for Signal/Slot System?

我正在尝试用 Kotlin 开发一个简单的 signals/slots 系统。这是我目前所拥有的:

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 需要...嗯... "signaled" 时,就会使用 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)

关于如何从这里处理事情有什么建议吗?

这是因为Function is an empty interface (source).

实际上有invoke个运算符的各种函数类型都一一定义here,如Function0Function1

我认为您无法创建一个 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>。)