In the new Swift API design guidelines, the commonly-used Type
suffix for protocols is being dropped. While this is easy to do for protocols that are stand-alone (SequenceType
becomes Sequence
), I'm not sure how to update my APIs in which a protocol provides the base for an implementation. Here's some examples from popular frameworks:
Result
, a concrete success/fail enumeration, and ResultType
, a generic base protocol for a success/fail type, to which Result
conforms.Signal
and SignalProducer
, which are backed by SignalType
and SignalProducerType
.In both cases, much of the implementation is in extensions of the protocols, allowing extensions to use the full power of type constraints, and allowing the implementations to be generic. This is different from the case of protocols with AnySequence
-style type-erasing types: you aren't really expected to implement these protocols on your own, or unify disparate types.
Swift 4 allows multiple protocols to be called at once with the help of protocol composition.
Protocol composition is the process of combining multiple protocols into a single protocol. You can think of it as multiple inheritance. With protocol DoSomething , below, class HasSomethingToDo is able to do whatShouldBeDone and anotherThingToBeDone . print("I did Something!")
A protocol defines a blueprint of methods, properties, and other requirements that suit a particular task or piece of functionality. The protocol can then be adopted by a class, structure, or enumeration to provide an actual implementation of those requirements.
To create a protocol, use the protocol keyword followed by the name you want and defined by the curly braces. Protocols can be of 2 types: read-only/read-write. Read-only means you can only get the variable, but you cannot set it. Read-write means you can both set and get properties.
I would advise using the suffix Protocol
. This is consistent with how the standard library have stripped the Type
suffix from protocols, as stated in SE-0006:
On high level, the changes can be summarized as follows.
- Strip
Type
suffix from protocol names. In a few special cases this means adding aProtocol
suffix to get out of the way of type names that are primary (though most of these we expect to be obsoleted by Swift 3 language features).
For example, GeneratorType
was renamed to IteratorProtocol
.
And, for example, is also how both Result & ReactiveSwift have updated their APIs for Swift 3. ResultType
was renamed to ResultProtocol
(in this commit), and SignalType
was renamed to SignalProtocol
, and SignalProducerType
was renamed to SignalProducerProtocol
(in this commit).
Although it's worth noting that in a vast majority of these cases, such protocols only exist as a workaround for the lack of parameterised extensions.
For example, we cannot currently say:
struct SomeGenericThing<T> { var value: T } extension <T> Array where Element == SomeGenericThing<T>, T : Comparable { }
But introducing a protocol allows us to realise the generic placeholder(s) as associated type(s), which we can then use in constraints:
protocol SomeGenericThingProtocol { associatedtype T var value: T { get set } } struct SomeGenericThing<T> : SomeGenericThingProtocol { var value: T } extension Array where Element : SomeGenericThingProtocol, Element.T : Comparable { // ... }
Therefore once parameterised extensions are supported, we'll be able to do away with such protocols.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With