Swift Self作为泛型回调的参数类型

Swift Self作为泛型回调的参数类型,swift,callback,associated-types,Swift,Callback,Associated Types,我试图为每种支持特定协议的类型实现通用广播功能。例如: protocol Proto { typealias ItemType typealias Callback = (Self, ItemType) func register(tag: String, cb: Callback) func unregister(tag: String) } class Foo : Proto { typealias ItemType = Int func

我试图为每种支持特定协议的类型实现通用广播功能。例如:

protocol Proto {
    typealias ItemType
    typealias Callback = (Self, ItemType)

    func register(tag: String, cb: Callback)
    func unregister(tag: String)
}

class Foo : Proto {
    typealias ItemType = Int

    func register(tag: String, cb: (Foo, Int)) {

    }

    func unregister(tag: String) {

    }
}

func bc <T: Proto> (p: T, value: T.ItemType, os: [String: T.Callback]) {
    for (k, v) in os {
        v(p, value) // error: cannot invoke v with argument list of...
    }
}
协议协议协议{
类型别名ItemType
typealias回调=(Self,ItemType)
func寄存器(标记:字符串,cb:回调)
func取消注册(标记:字符串)
}
Foo类:Proto{
typealias ItemType=Int
func寄存器(标记:String,cb:(Foo,Int)){
}
func取消注册(标记:字符串){
}
}
func bc(p:T,value:T.ItemType,os:[字符串:T.Callback]){
对于操作系统中的(k,v){
v(p,value)//错误:无法使用参数列表调用v。。。
}
}

问题是如何实现
bc
功能,对吗?

我认为swift在这个地方有缺陷。也许你可以用

protocol Proto {
    typealias ItemType

    func register(tag: String, cb: (Self, Self.ItemType)->())
    func unregister(tag: String, cb: (Self, Self.ItemType)->())
}

class Foo : Proto {

    func register(tag: String, cb: (Foo, Int)->()) {

    }
    func unregister(tag: String, cb: (Foo, Int)->()) {

    }
}

func bc <T: Proto> (p: T, value: T.ItemType, os: [String : (T,T.ItemType)->()]) {
    for (_, vc) in os {
        vc(p, value) // error: cannot invoke v with argument list of...
    }
}
协议协议协议{
类型别名ItemType
func寄存器(标记:String,cb:(Self,Self.ItemType)->())
func取消注册(标记:String,cb:(Self,Self.ItemType)->())
}
Foo类:Proto{
func寄存器(标记:String,cb:(Foo,Int)->()){
}
func unregister(标记:String,cb:(Foo,Int)->()){
}
}
func bc(p:T,value:T.ItemType,os:[字符串:(T,T.ItemType)->()){
对于操作系统中的(uvc){
vc(p,value)//错误:无法使用参数列表调用v。。。
}
}

您是否试图调用
T.Callback
的初始化器?不,只是一个闭包
v
是对闭包的引用,例如添加在Foo.register中。我们的目标是用相同的参数调用每个注册的回调函数。这很有效,感谢您的解决方案。主要缺点是它使您复制过去的类型定义。