Невозможно преобразовать значение типа '(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 тоже.

Другие вопросы по тегам