Es ist möglich, Erweiterungen zu vorhandenen Swift-Objekttypen mithilfe von Erweiterungen hinzuzufügen, wie in der Sprachspezifikation beschrieben .
Infolgedessen können Erweiterungen wie die folgenden erstellt werden:
extension String {
var utf8data:NSData {
return self.dataUsingEncoding(NSUTF8StringEncoding, allowLossyConversion: false)!
}
}
Was ist jedoch die beste Benennungspraxis für Swift-Quelldateien, die solche Erweiterungen enthalten?
In der Vergangenheit sollte die Konvention extendedtype+categoryname.m
für den Objective-C-Typ verwendet werden, wie im Objective-C-Handbuch erläutert . Das Swift-Beispiel hat jedoch keinen Kategorienamen, und es String.swift
erscheint nicht angemessen , ihn aufzurufen .
Die Frage ist also: String
Wie soll die schnelle Quelldatei angesichts der obigen Erweiterung heißen?
ios
objective-c
swift
xcode
AlBlue
quelle
quelle
ClassName+ExtensionName
Format folgten und die ich nicht zu viele Leute sehe, die sie noch verwenden. Außerdem finde ich das klobig, anstatt nur Klassen und Erweiterungen zusammen zu definieren oder der Datei einen besseren Namen zu gebenFooAbleTypes
und Instanzen insgesamt zu definieren.Extensions.swift
. Auf diese Weise verlieren Sie nicht den Überblick und Neulinge in der Codebasis werden sie sofort bemerken. Und ich würde es vorziehen, einmalige Erweiterungen für die Datei, in der sie benötigt werden, privat zu halten.Antworten:
Die meisten Beispiele, die ich gesehen habe, ahmen den Objective-C-Ansatz nach. Die obige Beispielerweiterung wäre:
String+UTF8Data.swift
Die Vorteile sind, dass die Namenskonvention leicht verständlich macht, dass es sich um eine Erweiterung handelt und welche Klasse erweitert wird.
Das Problem bei der Verwendung
Extensions.swift
oder sogarStringExtensions.swift
ist, dass es nicht möglich ist, den Zweck der Datei anhand ihres Namens abzuleiten, ohne auf deren Inhalt zu achten.Die Verwendung
xxxable.swift
des von Java verwendeten Ansatzes funktioniert in Ordnung für Protokolle oder Erweiterungen, die nur Methoden definieren. Im obigen Beispiel wird jedoch ein Attribut definiert,UTF8Dataable.swift
das grammatikalisch wenig sinnvoll ist.quelle
ExtendedType+Functionality.swift
, empfiehlt es sich, alleString
Erweiterungen beispielsweise in ihren eigenen Unterordner (dhString
oderString Extensions
) unter demExtensions
Ordner zu sortieren ? Oder ist es besser, alle Erweiterungsdateien auf derselben Ebene unter demExtensions
Ordner zu speichern ?Es gibt keine Swift-Konvention. Halte es einfach:
Ich erstelle eine Datei für jede Klasse, die ich erweitere. Wenn Sie für alle Erweiterungen eine einzige Datei verwenden, wird diese schnell zu einem Dschungel.
quelle
Ich bevorzuge es,
StringExtensions.swift
bis ich zu viele Dinge hinzugefügt habe, um die Datei in etwas wieString+utf8Data.swift
und aufzuteilenString+Encrypt.swift
.Wenn Sie ähnliche Dateien zu einer kombinieren, wird Ihr Gebäude schneller. Siehe Optimieren von Swift-Build-Zeiten
quelle
Wenn Sie über eine vom Team vereinbarte Reihe allgemeiner und verschiedener Verbesserungen verfügen, funktioniert das Zusammenfassen als Extensions.swift als Keep-It-Simple-Lösung der ersten Ebene. Wenn Ihre Komplexität jedoch zunimmt oder die Erweiterungen komplexer werden, ist eine Hierarchie erforderlich, um die Komplexität zu kapseln. Unter solchen Umständen empfehle ich die folgende Übung mit einem Beispiel.
Ich hatte eine Klasse, die mit meinem Backend spricht
Server
. Es wurde immer größer und deckte zwei verschiedene Ziel-Apps ab. Einige Leute mögen eine große Datei, teilen sich aber logischerweise mit Erweiterungen auf. Ich bevorzuge es, jede Datei relativ kurz zu halten, deshalb habe ich die folgende Lösung gewählt.Server
ursprünglichCloudAdapterProtocol
alle seine Methoden angepasst und implementiert. Was ich getan habe, war, das Protokoll in eine Hierarchie umzuwandeln, indem ich es auf untergeordnete Protokolle verweisen ließ:In
Server.swift
habe ichServer.swift
Implementiert dann einfach die Kernserver-API, um den Server festzulegen und die API-Version abzurufen. Die eigentliche Arbeit ist in zwei Dateien aufgeteilt:Diese implementieren die jeweiligen Protokolle.
Es bedeutet, dass Sie Importdeklarationen in den anderen Dateien haben müssen (in diesem Beispiel für Alamofire), aber meiner Ansicht nach ist dies eine saubere Lösung hinsichtlich der Trennung von Schnittstellen.
Ich denke, dieser Ansatz funktioniert genauso gut mit extern festgelegten Klassen wie mit Ihren eigenen.
quelle
Warum ist das überhaupt eine Debatte? Soll ich alle meine Unterklassen in eine Datei namens _Subclasses.swift einfügen? Ich denke nicht. Swift hat einen modulbasierten Namensabstand. Um eine bekannte Swift-Klasse zu erweitern, ist eine Datei erforderlich, die für ihren Zweck spezifisch ist. Ich könnte ein großes Team haben, das eine Datei namens UIViewExtensions.swift erstellt, die keinen Zweck ausdrückt und Entwickler verwirrt und leicht in dem Projekt dupliziert werden kann, das nicht erstellt werden würde. Die Objective-C-Namenskonvention funktioniert einwandfrei. Bis Swift einen echten Namensabstand aufweist, ist dies der beste Weg.
quelle
Anstatt meine Kommentare überall hinzuzufügen, tauche ich sie alle hier in einer Antwort auf.
Persönlich verfolge ich einen hybriden Ansatz, der sowohl eine gute Benutzerfreundlichkeit als auch Klarheit bietet und gleichzeitig die API-Oberfläche für das Objekt, das ich erweitere, nicht überfüllt.
Zum Beispiel würde alles, was Sinn macht , für eine beliebige Zeichenfolge verfügbar zu sein ,
StringExtensions.swift
wietrimRight()
undremoveBlankLines()
.Wenn ich jedoch eine Erweiterungsfunktion hätte, wie
formatAsAccountNumber()
sie nicht in diese Datei aufgenommen würde, da 'Kontonummer' natürlich nicht für alle Zeichenfolgen gilt und nur im Zusammenhang mit Konten sinnvoll ist. In diesem Fall würde ich eine Datei mit dem NamenStrings+AccountFormatting.swift
oder vielleicht sogarStrings+CustomFormatting.swift
mit einerformatAsAccountNumber()
Funktion erstellen, wenn es mehrere Arten / Möglichkeiten gibt, sie tatsächlich zu formatieren.Tatsächlich habe ich in diesem letzten Beispiel mein Team aktiv davon abgehalten, solche Erweiterungen zu verwenden, und würde stattdessen so etwas
AccountNumberFormatter.format(String)
empfehlen, da dies dieString
API-Oberfläche überhaupt nicht berührt , wie es nicht sein sollte. Die Ausnahme wäre, wenn Sie diese Erweiterung in derselben Datei definieren würden, in der sie verwendet wird, aber dann hätte sie sowieso keinen eigenen Dateinamen.quelle
Ich bevorzuge es
+
, die Tatsache zu unterstreichen, dass es Erweiterungen enthält:String+Extensions.swift
Und wenn die Datei zu groß wird, können Sie sie für jeden Zweck aufteilen:
String+UTF8Data.swift
String+Encrypt.swift
quelle