6
votes

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?

1

1 Answers

1
votes

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