Conforming to multiple instances of a generic protocol
Asked Answered
P

1

6

I have a Swift protocol MessageHandler with an associated type, a few different Message types, and also a class X:

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

class FooMessage {}
class BarMessage {}

class X {}

Now how do I make X able to handle both FooMessages and BarMessages?

Trying this:

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

simply gives a "redundant conformance" error.

This:

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) {}
}

makes the compiler say that X does not conform to either protocols. However, after removing the function from one of them, I get a more interesting complaint: "'FooMessageHandler' requires the types 'BarMessage' and 'FooMessage' be equivalent".

In C++, X would have two bases: MessageHandler<FooMessage> and MessageHandler<BarMessage>. How do I achieve something like that in Swift?

Pulchritude answered 8/4, 2019 at 15:35 Comment(0)
S
1

A protocol, conformed to by the message types, could enable you to provide a single type as the associatedtype.

Inside your handle(message:) you could then check the type of the message and handle accordingly.

protocol BazMessage {}

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

extension X: MessageHandler {
    typealias Message = BazMessage
    func handle(message: BazMessage) {}
}
Shaunda answered 8/4, 2019 at 17:7 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.