Mithilfe von Erweiterungen können Sie Ihre Protokollkonformitätserklärung neben den Methoden, die dieses Protokoll implementieren, beibehalten.
Wenn es keine Erweiterungen waren, stellen Sie sich Ihre Art, wie erklärt:
struct Queue<T>: SequenceType, ArrayLiteralConvertible, Equatable, Printable, Deflectable, VariousOtherables {
// lotsa code...
// and here we find the implementation of ArrayLiteralConvertible
/// Create an instance containing `elements`.
init(arrayLiteral elements: T…) {
etc
}
}
Kontrast dies bei der Verwendung von Erweiterungen, in dem Sie die Umsetzung der Protokolle mit den spezifischen Methoden bündeln, die sie implementieren:
struct Queue<T> {
// here go the basics of queue - the essential member variables,
// maybe the enqueue and dequeue methods
}
extension SequenceType {
// here go just the specifics of what you need for a sequence type
typealias Generator = GeneratorOf<T>
func generate() -> Generator {
return GeneratorOf {
// etc.
}
}
}
extension Queue: ArrayLiteralConvertible {
init(arrayLiteral elements: T...) {
// etc.
}
}
Ja, Sie können Ihre Protokollimplementierungen mit // MARK
markieren (und beachten Sie, Sie können beide Techniken kombinieren), aber Sie würden immer noch über den Anfang der Datei aufgeteilt werden, wo die Erklärung der Protokollunterstützung würde b e und der Hauptteil der Datei, in der sich Ihre Implementierung befindet.
Denken Sie auch daran, wenn Sie ein Protokoll implementieren, erhalten Sie hilfreiche (wenn auch etwas wortreiche) Rückmeldungen von der IDE, während Sie fortfahren und Ihnen sagen, was Sie noch implementieren müssen. Das Verwenden von Erweiterungen, um jedes Protokoll einzeln zu machen, macht es für mich viel einfacher, als alles auf einmal zu tun (oder von oben nach unten zu springen, wenn du sie hinzufügst).
Vor diesem Hintergrund ist es natürlich, andere, nicht-Protokoll, sondern verwandte Methoden auch in Erweiterungen zu gruppieren.
Ich finde es tatsächlich manchmal frustrierend, wenn Sie nicht können dies tun. Zum Beispiel
extension Queue: CollectionType {
// amongst other things, subscript get:
subscript(idx: Index) -> T {
// etc
}
}
// all MutableCollectionType adds is a subscript setter
extension Queue: MutableCollectionType {
// this is not valid - you’re redeclaring subscript(Index)
subscript(idx: Int) -> T {
// and this is not valid - you must declare
// a get when you declare a set
set(val) {
// etc
}
}
}
Also müssen Sie beide innerhalb der gleichen Erweiterung implementieren.
Verwenden Sie, was Sie bevorzugen, aber die Erweiterung macht es expliziter als nur 'MARK:', deutlich, wo es beginnt und wo es endet. Ehrlich gesagt, es ist kein Entweder-oder-Problem, da ich sowohl "MARK:" als auch eine "Erweiterung" verwenden werde. Ein weiterer Vorteil von 'extension' ist, dass Sie diesen Code einfach falten können (z. B." Editor "-" Code Folding ... "-" Falten "oder klicken Sie auf den schattierten linken Rand). – Rob