Невозможно преобразовать значение типа '(T) -> Void'
Пример:
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'
}
}
Я получаю ошибку:
Cannot convert value of type '(T) -> Void' to expected argument type '(CommonProtocol) -> Void'
Вопрос:
Зачем
(T) -> Void
не может быть приведен к(CommonProtocol) -> Void
?T
явно объявлен как<T: CommonProtocol>
Это мой первый вопрос, если у вас есть предложения, пожалуйста, не стесняйтесь обращаться ко мне
1 ответ
Вам не нужно делать func add
родовой. Когда вы указываете в func add<T: CommonProtocol>...
вы явно указываете компилятору, что ваша функция принимает все типы, которые наследуют CommonProtocol
но ваш Wrapper указывает, что принимает CommonProtocol
не наследуемые типы.
Решение
Либо введите-стереть класс C:
Class C<T: CommonProtocol> {
var wrapper: Wrapper<T>
....
}
или если тип T на самом деле не имеет значения для вас, то:
func add(_ handler: @escaping (CommonProtocol) -> Void)
но второй не имеет смысла вообще. Вы должны понизить это всякий раз, когда будете использовать этот метод (и понижения очень плохи:D)
Примечание: это на самом деле не связано с этим вопросом, но один из вариантов - стереть CommonProtocol
тоже.