例子:
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) -> Void
?T
显式声明为
<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 the
CommonProtocol
。