例子:

struct Wrapper<T> {
    var key: Int = 0
    var listeners: [Int: (T) -> Void] = Dictionary()

    mutating func add(_ handler:@escaping (T) -> Void) {
        self.key += 1
        self.listeners[self.key] = handler
    }

    func get(key: Int) -> (T) -> Void {
        return self.listeners[key]!
    }
}

测试协议:
protocol CommonProtocol {

}

创建测试类包装的类
class C {
    var wrapper: Wrapper = Wrapper<CommonProtocol>()

    func add<T: CommonProtocol>(_ handler: @escaping (T) -> Void) {
        self.wrapper.add(handler) //Cannot convert value of type '(T) -> Void' to expected argument type '(CommonProtocol) -> Void'
    }
}

Image with error
我得到错误:
Cannot convert value of type '(T) -> Void' to expected argument type '(CommonProtocol) -> Void'

问题:
为什么不能将(T) -> Void转换为(CommonProtocol) -> VoidT
显式声明为<T: CommonProtocol>
这是我的第一个问题,如果你有什么建议,请随时与我联系

最佳答案

您不需要将func add设为泛型。
当您在func add<T: CommonProtocol>...中指定时,显式地告诉编译器您的函数接受继承CommonProtocol的所有类型,但是包装器指定接受CommonProtocol而不是继承的类型。
解决方案
任一类型擦除C类:

Class C<T: CommonProtocol> {
    var wrapper: Wrapper<T>
    ....
}

或者如果类型T对你来说并不重要,那么:
func add(_ handler: @escaping (CommonProtocol) -> Void)

但第二个根本没有意义。每次使用此方法时都必须对其进行向下转换(向下转换非常糟糕:D)
注意:它实际上与这个问题无关,但您的一个选项是键入erase theCommonProtocol

10-08 03:31