Angenommen, wir passen Ihr Protokoll für den Moment an, um eine Routine hinzuzufügen, die den zugehörigen Typ verwendet:
public protocol RequestType: class {
associatedtype Model
var path: String { get set }
func frobulateModel(aModel: Model)
}
Und Swift sollte es Ihnen ermöglichen, ein Array so zu erstellen, RequestType
wie Sie es möchten. Ich könnte ein Array dieser Anforderungstypen an eine Funktion übergeben:
func handleQueueOfRequests(queue: [RequestType]) {
// frobulate All The Things!
for request in queue {
request.frobulateModel(/* What do I put here? */)
}
}
Ich komme zu dem Punkt, an dem ich alle Dinge frobulieren möchte, aber ich muss wissen, welche Art von Argument in den Aufruf übergehen soll. Einige meiner RequestType
Entitäten könnten ein nehmen LegoModel
, einige könnten ein nehmen PlasticModel
, und andere könnten ein nehmen PeanutButterAndPeepsModel
. Swift ist mit der Mehrdeutigkeit nicht zufrieden, sodass Sie keine Variable eines Protokolls deklarieren können, dem ein Typ zugeordnet ist.
Gleichzeitig ist es durchaus sinnvoll, beispielsweise ein Array zu erstellen, RequestType
wenn wir wissen, dass alle das verwenden LegoModel
. Dies scheint vernünftig und ist es auch, aber Sie brauchen eine Möglichkeit, dies auszudrücken.
Eine Möglichkeit, dies zu tun, besteht darin, eine Klasse (oder Struktur oder Aufzählung) zu erstellen, die dem Namen des abstrakten Modelltyps einen realen Typ zuordnet:
class LegoRequestType: RequestType {
typealias Model = LegoModel
// Implement protocol requirements here
}
Jetzt ist es völlig vernünftig, eine Reihe von zu deklarieren, LegoRequestType
denn wenn wir frobulate
alle wollten, wissen wir, dass wir LegoModel
jedes Mal eine übergeben müssen.
Diese Nuance mit zugeordneten Typen macht jedes Protokoll, das sie verwendet, zu etwas Besonderem. Die Swift Standard Library verfügt über solche Protokolle, insbesondere Collection
oder Sequence
.
Damit Sie ein Array von Dingen erstellen können, die das Collection
Protokoll implementieren , oder eine Reihe von Dingen, die das Sequenzprotokoll implementieren, verwendet die Standardbibliothek eine Technik namens "Typlöschung", um die Strukturtypen AnyCollection<T>
oder zu erstellen AnySequence<T>
. Die Typ-Lösch-Technik ist in einer Stapelüberlauf-Antwort ziemlich komplex zu erklären, aber wenn Sie im Web suchen, gibt es viele Artikel darüber.
Ich kann ein Video von Alex Gallagher über Protokolle mit zugehörigen Typen (PATs) auf YouTube empfehlen .