Использование расширений позволяет сохранять декларацию соответствия протокола рядом с методами, реализующими этот протокол.
Если бы не было никаких расширений, представьте объявить тип как:
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
}
}
Contrast это с помощью расширений, где вы Bundle вместе реализацию протоколов с этими специфическими методами, которые реализуют его:
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.
}
}
Да, вы можете пометить свои реализации протокола с помощью // MARK
(и помните, что вы можете комбинировать обе технологии), но вы все равно будете разделены по верхней части файла, где объявление поддержки протокола будет b e и тело файла, где выполняется ваша реализация.
Кроме того, помните, если вы реализуете протокол, вы получите полезную (если немного подробную) обратную связь от IDE по мере того, как вы расскажете, что вам осталось реализовать. Использование расширений для каждого протокола по одному делает его (для меня) намного проще, чем делать все за один раз (или прыгать назад и вперед сверху вниз, когда вы их добавляете).
Учитывая это, тогда естественно группировать другие, не протокольные, но связанные с ними методы и в расширения.
Я нахожу это разочаровывающим иногда, когда вы не может сделать это. Например,
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
}
}
}
Таким образом, вы должны реализовать оба устройства в пределах одного расширения.
Используйте то, что вам больше нравится, но расширение делает его более явным, чем просто «MARK:», четко обозначая, где он начинается и где он заканчивается. Честно говоря, это не проблема/или проблема, так как я буду использовать оба «MARK:» и «extension». Еще одно преимущество «расширения» заключается в том, что вы можете легко сбрасывать этот код (например, «Редактор» - «Складка кода ...» - «Сложить» или щелкнуть по затененному левому краю). – Rob