Соответствие нескольким экземплярам универсального протокола - PullRequest
6 голосов
/ 08 апреля 2019

У меня есть протокол Swift MessageHandler со связанным типом, несколькими различными типами сообщений, а также классом X:

protocol MessageHandler { 
    associatedtype Message
    func handle(message: Message)
}

class FooMessage {}
class BarMessage {}

class X {}

Теперь, как мне сделать X способным обрабатывать как FooMessages, так и BarMessages?

Попытка:

extension X: MessageHandler {
    typealias Message = FooMessage
    func handle(message: FooMessage) {}
}
extension X: MessageHandler {
    typealias Message = BarMessage
    func handle(message: BarMessage) {}
}

просто выдает ошибку «избыточного соответствия».

Это:

protocol FooMessageHandler: MessageHandler where Message == FooMessage {}
protocol BarMessageHandler: MessageHandler where Message == BarMessage {}

extension X: FooMessageHandler {
    func handle(message: FooMessage) {}
}
extension X: BarMessageHandler {
    func handle(message: BarMessage) {}
}

заставляет компилятор сказать, что X не соответствует ни одному из протоколов.Однако после удаления функции из одного из них я получаю более интересную жалобу: «FooMessageHandler требует, чтобы типы« BarMessage »и« FooMessage »были эквивалентными».

В C ++ X будет иметь две базы: MessageHandler<FooMessage> и MessageHandler<BarMessage>.Как мне добиться чего-то подобного в Swift?

1 Ответ

1 голос
/ 08 апреля 2019

Протокол, соответствующий типам сообщений, может позволить вам предоставить один тип как associatedtype.

Внутри вашего handle(message:) вы можете проверить тип сообщения и обработать его соответствующим образом.

protocol BazMessage {}

class FooMessage: BazMessage {}
class BarMessage: BazMessage {}

extension X: MessageHandler {
    typealias Message = BazMessage
    func handle(message: BazMessage) {}
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...