Как лучше всего именовать файлы Swift, которые добавляют расширения к существующим объектам?

95

Можно добавлять расширения к существующим типам объектов Swift с использованием расширений, как описано в спецификация языка.

В результате можно создавать расширения, такие как:

extension String {
    var utf8data:NSData {
        return self.dataUsingEncoding(NSUTF8StringEncoding, allowLossyConversion: false)!
    }
}

Однако, какая лучшая практика именования для исходных файлов Swift, содержащих такие расширения?

В прошлом соглашение заключалось в использовании extendedtype+categoryname.m для Objective-C типа, как описано в руководстве Objective-C. Но пример Swift не имеет названия категории, и вызов его String.swift кажется нецелесообразным.

Итак, вопрос: учитывая вышеприведенное расширение String, какой должен быть вызван быстрый файл-источник?

  • 2
    Это не вопрос пересмотра кода - меня не волнует этот конкретный пример, я хочу знать, каково соглашение о быстром именовании.
  • 2
    Там нет соглашения об именах. Единственное, что мы должны сделать, - это категории из Objective-C, которые всегда следовали ClassName+ExtensionName , и которые, как я вижу, слишком много людей все еще используют. Кроме того, я нахожу это неуклюжим вместо того, чтобы просто определять классы и расширения вместе или давать файлу лучшее имя, например FooAbleTypes и определять экземпляры в совокупности.
Показать ещё 5 комментариев
Теги:

5 ответов

121
Лучший ответ

Большинство примеров, которые я видел, имитируют подход Objective-C. Вышеприведенный пример выше:

String+UTF8Data.swift

Преимущества заключаются в том, что соглашение об именах позволяет легко понять, что это расширение и какой класс расширяется.

Проблема с использованием Extensions.swift или даже StringExtensions.swift заключается в том, что невозможно определить цель файла по его имени, не глядя на его содержимое.

Использование подхода xxxable.swift, используемого Java, хорошо подходит для протоколов или расширений, которые определяют методы. Но опять же, пример выше определяет атрибут так, что UTF8Dataable.swift не делает много грамматического смысла.

  • 1
    Хотя можно сделать вывод о том, что расширяется соглашением об именах, это IHMO - ненужное осложнение. Вместо тонны файлов <name> + <extention> .swift у меня есть один файл extensions.swift, который я обычно использую для каждого проекта. Внутренний файл организован так, что найти конкретный расширенный класс очень просто.
  • 13
    Этот ответ, <name> + <extention> .swift, действительно является способом, которым Xcode делает это при создании подклассов NSManagedObject для Core Data в Xcode 8. Пример: Foo + CoreDataProperties.swift.
Показать ещё 2 комментария
4

Нет соглашения о быстрой встрече. Держите это просто:

StringExtensions.swift

Я создаю один файл для каждого класса, который я расширяю. Если вы используете один файл для всех расширений, он быстро превратится в джунгли.

  • 6
    Это не кажется многократно используемым.
  • 0
    По сравнению с?
Показать ещё 2 комментария
2

Мое предпочтение заключается в том, чтобы поставить "Extension_" в начале файла. (Я поместил все связанные расширения в один и тот же файл.)

Таким образом, все файлы расширения вместе, в алфавитном порядке, находятся в моем каталоге приложений и навигаторе Xcode. Конечно, в навигаторе я тоже могу их сгруппировать.

Итак, расширение, связанное со строкой, должно войти в Extension_String.swift

0

Я предпочитаю StringExtensions.swift, пока не добавлю слишком много вещей, чтобы разбить файл на что-то вроде String+utf8Data.swift и String+Encrypt.swift.

Еще одна вещь, чтобы объединить похожие файлы в один, сделает ваше здание более быстрым. См. Optimizing-Swift-Build-Times

0

Если у вас есть согласованный по команде набор общих и разных улучшений, объединив их вместе как Extensions.swift, он будет использоваться как решение первого уровня Keep-It-Simple. Однако по мере того, как ваша сложность возрастает или расширяются расширения, требуется иерархия для инкапсуляции сложности. В таких обстоятельствах я рекомендую следующую практику с примером.

У меня был класс, который говорил с моим back-end, называемым Server. Он стал расти больше, чтобы охватить два разных целевых приложения. Некоторые люди любят большой файл, но просто логически разделяются с расширениями. Мое предпочтение заключается в том, чтобы держать каждый файл относительно коротким, поэтому я выбрал следующее решение. Server первоначально соответствовал CloudAdapterProtocol и реализовал все его методы. То, что я сделал, это превратить протокол в иерархию, обратившись к подчиненным протоколам:

protocol CloudAdapterProtocol: ReggyCloudProtocol, ProReggyCloudProtocol {
    var server: CloudServer {
        get set
    }
    func getServerApiVersion(handler: @escaping (String?, Error?) -> Swift.Void)
}

В Server.swift у меня есть

import Foundation
import UIKit
import Alamofire
import AlamofireImage

class Server: CloudAdapterProtocol {
.
.
func getServerApiVersion(handler: @escaping (String?, Error?) -> Swift.Void) {
.
.
}

Server.swift затем просто реализует API-интерфейс основного сервера для настройки сервера и получения версии API. Реальная работа делится на два файла:

Server_ReggyCloudProtocol.swift
Server_ProReggyCloudProtocol.swift

Они реализуют соответствующие протоколы.

Это означает, что вам нужно иметь декларации импорта в других файлах (для Alamofire в этом примере), но это чистое решение с точки зрения разделения интерфейсов на мой взгляд.

Я думаю, что этот подход работает одинаково с внешними заданными классами, а также с вашими собственными.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню