Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Conforming to multiple instances of a generic protocol

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?

like image 583
imre Avatar asked Apr 08 '19 15:04

imre


People also ask

What are generic protocols?

Generic Protocols are for procedures/techniques involving human participants that are used on a regular basis, and which form all or part of subsequent research projects or taught modules.

How many protocols can a Swift class adopt?

Since classes, structures and, enums can conform to more than one protocol, they can take the default implementation of multiple protocols.

How do you ensure the adoption of a protocol only by reference type?

You can limit protocol adoption to class types (and not structures or enumerations) by adding the AnyObject or class protocol to a protocol's inheritance list.

What is difference between protocol and delegate in Swift?

Protocol is a set of methods (either optional or required) that would be implemented by the class which conforms to that protocol. While, delegate is the reference to that class which conforms to that protocol and will adhere to implement methods defined in protocol.


1 Answers

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) {}
}
like image 130
Eric Kunz Avatar answered Sep 23 '22 05:09

Eric Kunz