In der Dokumentation werden nur verschachtelte Typen erwähnt, es ist jedoch nicht klar, ob sie als Namespaces verwendet werden können. Ich habe keine explizite Erwähnung von Namespaces gefunden.
Eine schnelle Strg-F-Suche in ihrem iBook zeigt keine Instanzen von Namespaces ... also gehe ich mit nein?
Justin Niessner
1
Ich weiß nicht, warum diese Frage geschlossen ist. Ich habe einen Namespace auf der Keynote auf der linken Seite des Swift-Symbols gesehen und kann immer noch keine Erwähnung in der Dokumentation finden ...
eonil
Ich konnte keine Informationen dazu finden, Google hat mich zu dieser Frage geführt :). Vielleicht wird eine der WWDC-Sitzungen etwas mehr Licht ins Dunkel bringen.
Zyphrax
Ich warte auch darauf, dass jemand im WWDC eine nette Erklärung findet.
Eonil
Eonils Antwort ist richtig. Sie verwenden Module in Xcode, um Ihre Klassen zu trennen.
Namespaces sind nicht pro Datei; Sie sind pro Ziel (basierend auf der Build-Einstellung "Product Module Name"). Am Ende hätten Sie also so etwas:
importFrameworkAimportFrameworkBFrameworkA.foo()
Alle Swift-Deklarationen werden als Teil eines Moduls betrachtet. Selbst wenn Sie " NSLog" sagen (ja, es existiert noch)), erhalten Sie das, was Swift als " Foundation.NSLog" ansieht .
Der Namensraum ist in Swift implizit. Alle Klassen (usw.) sind implizit von dem Modul (Xcode-Ziel) abhängig, in dem sie sich befinden. Es werden keine Klassenpräfixe benötigt
Scheint ganz anders zu sein, als ich gedacht habe.
Apple Dev-Foren ... Ich habe dort so viel Tumbleweed gesehen, dass Sie es nicht glauben würden!
Nicolas Miari
1
Der Link zu den Apple-Entwicklerforen ist jetzt unterbrochen, und Apple hat diesen Thread forums.developer.apple.comleider nicht in die neue Forenseite importiert .
Dai
2
@Dai Es scheint, dass wir deshalb Apple-Foren für Fragen und Antworten meiden sollten ... Aber die Mitglieder des Kernteams scheinen sich nicht so sehr für SO zu interessieren. Was für eine Tragödie.
Eonil
1
Was meinst du mit Tumbleweed?
Alexander Mills
148
Ich würde Swifts Namensraum als ehrgeizig beschreiben; Es wurde viel Werbung gemacht, die keiner sinnvollen Realität vor Ort entspricht.
In den WWDC-Videos heißt es beispielsweise, dass wenn ein Framework, das Sie importieren, eine Klasse MyClass und Ihr Code eine Klasse MyClass hat, diese Namen nicht in Konflikt stehen, da "name mangling" ihnen unterschiedliche interne Namen gibt. In Wirklichkeit aber sie tun Konflikt, in dem Sinne , dass Sie Ihren eigenen Code des MyClass gewinnt, und Sie nicht angeben können „Nein , nein, ich meine die MyClass im Rahmen“ - sagt TheFramework.MyClassnicht funktioniert (der Compiler weiß , was du meinst , aber es heißt, dass es eine solche Klasse im Framework nicht finden kann).
Ich habe die Erfahrung gemacht, dass Swift daher nicht im geringsten einen Namensraum hat. Als ich eine meiner Apps von Objective-C auf Swift umstellte, erstellte ich ein eingebettetes Framework, weil es so einfach und cool war. Beim Importieren des Frameworks werden jedoch alle Swift-Inhalte in das Framework importiert. Daher gibt es wieder nur einen Namespace, der global ist. Und es gibt keine Swift-Header, sodass Sie keine Namen verbergen können.
BEARBEITEN: In Seed 3 wird diese Funktion jetzt im folgenden Sinne online geschaltet: Wenn Ihr Hauptcode MyClass enthält und Ihr Framework MyFramework MyClass enthält, überschattet das erstere standardmäßig das letztere, aber Sie können das im Framework erreichen unter Verwendung der Syntax MyFramework.MyClass. Wir haben also tatsächlich die Grundlagen eines bestimmten Namespace!
EDIT 2: In Seed 4 haben wir jetzt Zugriffskontrollen! Außerdem habe ich in einer meiner Apps ein eingebettetes Framework und sicher war alles standardmäßig ausgeblendet und ich musste alle Teile der öffentlichen API explizit verfügbar machen. Dies ist eine große Verbesserung.
Danke für diese Antwort. Es funktioniert nicht nur mit Frameworks, sondern auch mit der Standardbibliothek. Sie können beispielsweise das Array "überschreiben". Dann bezieht sich "Array" auf Ihre eigene benutzerdefinierte Array-Klasse, und das Array der Standard Library ist als "Swift.Array" verfügbar.
George
3
@ George Und ähnlich für NSArray; Wenn Sie es überschatten, können Sie es immer noch als bezeichnen Foundation.NSArray.
Matt
1
Also ohne die Geschichte des Denkens nach Namespaces in den Betas sortieren zu müssen: Wo steht diese Antwort jetzt?
Dan Rosenstark
1
@Yar wie in den Änderungen angegeben. Der Modulname ist ein optionaler Namespace, wenn Unklarheiten bestehen, und es gibt jetzt Datenschutz, sodass Modulnamen ausgeblendet werden, sofern sie nicht offengelegt werden und ein Name auf eine Datei beschränkt werden kann.
Matt
2
Das hat mich schon lange beschäftigt. Es scheint, dass Swift-Projekte aufgrund der Behauptungen von Apple kein Präfix verwenden sollten. Derzeit ist jedoch auch mit den Zugriffsmodifikatoren noch ein Präfix erforderlich. Während Sie im Apple-Framework nicht mit Paket- oder privaten Klassen in Konflikt geraten, wird alles, was als öffentlich deklariert wird, z. B. String, wenn Sie dies erneut deklarieren, oder eine neue Klasse, Ihre verwenden, es sei denn, Sie haben es sich zur Gewohnheit gemacht Bezug auf alle Klassen mit seinem Namespace .... nicht gut imo.
Oscar Gomez
19
Während ich damit experimentierte, erstellte ich diese "Namespace" -Klassen in ihren eigenen Dateien, indem ich das Root- "Paket" erweiterte. Ich bin mir nicht sicher, ob dies gegen Best Practices verstößt oder ob es irgendwelche Auswirkungen hat, die mir bewusst sind (?)
extensionPackageOne{classClass{var name:Stringinit(name:String){self.name = name
}}}
PackageTwoClass.swift
extensionPackageTwo{classClass{var name:Stringinit(name:String){self.name = name
}}}
Bearbeiten:
Ich habe gerade herausgefunden, dass das Erstellen von "Unterpaketen" im obigen Code nicht funktioniert, wenn separate Dateien verwendet werden. Vielleicht kann jemand andeuten, warum das so ist?
Hinzufügen der folgenden Dateien zu den oben genannten:
extensionPackageOne.SubPackage{classClass{var name:Stringinit(name:String){self.name = name
}}}
Es wird ein Compilerfehler ausgegeben: 'SubPackage' ist kein Mitgliedstyp von 'PackageOne'.
Wenn ich den Code von PackageOneSubPackageClass.swift nach PackageOneSubPackage.swift verschiebe, funktioniert es. Jemand?
Bearbeiten 2:
Ich habe immer noch damit herumgespielt und herausgefunden (in Xcode 6.1 Beta 2), dass die Pakete durch Definieren in einer Datei in separaten Dateien erweitert werden können:
Ich bin mir nicht sicher, was Sie unter "Testen" verstehen, aber ich habe begonnen, meine App mit der oben genannten Technik zu erstellen, und sie scheint bisher mit der Einschränkung, die ich meinem obigen Eintrag hinzugefügt habe, gut zu funktionieren. Ich mache es hauptsächlich, weil ich es gewohnt bin, meinen Code auf diese Weise in anderen Sprachen zu organisieren, und wäre dankbar, wenn jemand mit mehr Wissen mir sagen könnte, dass es eine schlechte Idee ist, bis ich zu weit gehe! :)
bWlrYWphdWhvbmVu
1
mach weiter ... das ist es, was wir wollen ... um in der Lage zu sein, dieselbe Namensklasse in zwei verschiedenen Paketen zu haben, um existieren zu können und entsprechend zu referenzieren (was noch wichtiger ist, verschiedene Dateien) und wenn es nicht funktioniert, das Ganze Idee des Namespace ist eine Flop-Idee ...
user2727195
Gibt es Nebenwirkungen, bei denen "struct" zum Hacken von Namespaces verwendet wird?
Alex Nolasco
Nicht, dass ich in Bezug auf die Leistung einer solchen begegnet wäre. Xcode (6.1 GM) beschwert sich in einigen seltenen Fällen über nicht vorhandene Typen, aber ich glaube, dass dies der Fall sein kann, wenn Code nicht auch so strukturiert wird. Ich habe kürzlich ein Problem gelöst, indem ich alle Dateien zu meinem Testziel hinzugefügt habe, die keinen Sinn ergeben, aber das Problem gelöst haben. :)
Ich bin immer noch nicht so zufrieden mit der Art und Weise, wie Namespaces erstellt werden. Was ist, wenn ich zehn verschiedene Klassen in einem Namespace habe? Außerdem möchte ich lieber Klassen in ihren einzelnen Dateien behalten und keine aufblähen Datei / Struktur mit allen Klassen, Vorschläge Kevin.
user2727195
2
Ich frage mich, warum sie nicht daran gedacht haben, Pakete einzuschließen. Das ist es, was wir brauchen, keine Namespaces. Ich meine, schauen Sie sich andere Hochsprachen wie Java, C #, ActionScript an. Sie haben alle Pakete. Namespaces unterscheiden sich in diesem Zusammenhang nicht von der Verwendung von NS oder andere Präfixe für Ihre Projektklassen
user2727195
1
Ich frage mich, ob die Verwendung von Strukturen zum Hacken von Namespaces unbekannte Probleme verursachen kann.
Alex Nolasco
1
Dies ist eine gute Problemumgehung. Ich habe versucht, diesen Ansatz zu verwenden, musste aber sofort aufhören. Als ich versuchte, meine ansichtsbezogenen Klassen mit einem Namespace zu versehen (z. B. eine CustomTableViewCell), schlug die automatische Vervollständigung im Interface Builder dies nicht vor. Ich müsste den Klassennamen für die Ansicht manuell kopieren und einfügen, wenn ich diesen Ansatz verwendet hätte.
ArG
1
Normalerweise verwenden Sie ein enum, kein a struct, sodass Sie a nicht instanziieren können Foo.
Kevin
7
Swift verwendet Module ähnlich wie in Python (siehe hier und hier ) und wie @ Kevin Sylvestre vorgeschlagen hat, können Sie die verschachtelten Typen auch als Namespaces verwenden.
Und um die Antwort von @Daniel A. White zu erweitern, sprachen sie im WWDC schnell über die Module.
Ich suche nach Paketen wie Konstrukt, wie in Ihrem zweiten Link erwähnt. 6.4 Pakete (Python), Namespaces als verschachtelte Typen können nicht sehr weit gehen. Was ist, wenn ich 10 verschiedene Klassen und in verschiedenen Dateien in einem Namespace habe oder sagen wir a Paket???
user2727195
7
Namespaces sind nützlich, wenn Sie eine Klasse mit demselben Namen wie die Klasse in einem vorhandenen Framework definieren müssen.
Angenommen, Ihre App hat einen MyAppNamen und Sie müssen Ihre benutzerdefinierte deklarieren UICollectionViewController.
Sie müssen keine Präfixe und Unterklassen wie folgt erstellen:
Warum? . Denn was Sie deklariert haben, wird im aktuellen Modul deklariert , das Ihr aktuelles Ziel ist . Und UICollectionViewControllervon UIKitwird im UIKitModul deklariert .
Wie verwende ich es im aktuellen Modul?
var customController =UICollectionViewController()//your custom class
var uikitController =UIKit.UICollectionViewController()//class from UIKit
Wie kann man sie von einem anderen Modul unterscheiden?
var customController =MyApp.UICollectionViewController()//your custom class
var uikitController =UIKit.UICollectionViewController()//class from UIKit
Sie können extensionden genannten structs-Ansatz für den Namespace verwenden, ohne den gesamten Code nach rechts einrücken zu müssen. Ich habe mit diesem ein wenig Spielerei gewesen , und ich bin nicht sicher , würde ich so weit wie die Schaffung gehen Controllersund ViewsNamensräume wie im Beispiel unten, aber es funktioniert zeigen , wie weit es gehen kann:
Profiles.swift :
// Define the namespaces
structProfiles{structViews{}structViewControllers{}}
Profile / ViewControllers / Edit.swift
// Define your new class within its namespace
extensionProfiles.ViewControllers{classEdit:UIViewController{}}// Extend your new class to avoid the extra whitespace on the left
extensionProfiles.ViewControllers.Edit{overridefunc viewDidLoad(){// Do some stuff
}}
Profile / Ansichten / Edit.swift
extensionProfiles.Views{classEdit:UIView{}}extensionProfiles.Views.Edit{overridefunc drawRect(rect:CGRect){// Do some stuff
}}
Ich habe dies nicht in einer App verwendet, da ich diese Trennungsstufe noch nicht benötigt habe, aber ich denke, es ist eine interessante Idee. Dadurch sind keine Klassensuffixe wie das allgegenwärtige * ViewController-Suffix mehr erforderlich, das ärgerlich lang ist.
Es verkürzt jedoch nichts, wenn darauf verwiesen wird, wie in Methodenparametern wie diesen:
Antworten:
Beantwortet von SevenTenEleven im Apple Dev Forum :
Auch Chris Lattner twitterte über Namespace .
Scheint ganz anders zu sein, als ich gedacht habe.
quelle
forums.developer.apple.com
leider nicht in die neue Forenseite importiert .Ich würde Swifts Namensraum als ehrgeizig beschreiben; Es wurde viel Werbung gemacht, die keiner sinnvollen Realität vor Ort entspricht.
In den WWDC-Videos heißt es beispielsweise, dass wenn ein Framework, das Sie importieren, eine Klasse MyClass und Ihr Code eine Klasse MyClass hat, diese Namen nicht in Konflikt stehen, da "name mangling" ihnen unterschiedliche interne Namen gibt. In Wirklichkeit aber sie tun Konflikt, in dem Sinne , dass Sie Ihren eigenen Code des MyClass gewinnt, und Sie nicht angeben können „Nein , nein, ich meine die MyClass im Rahmen“ - sagt
TheFramework.MyClass
nicht funktioniert (der Compiler weiß , was du meinst , aber es heißt, dass es eine solche Klasse im Framework nicht finden kann).Ich habe die Erfahrung gemacht, dass Swift daher nicht im geringsten einen Namensraum hat. Als ich eine meiner Apps von Objective-C auf Swift umstellte, erstellte ich ein eingebettetes Framework, weil es so einfach und cool war. Beim Importieren des Frameworks werden jedoch alle Swift-Inhalte in das Framework importiert. Daher gibt es wieder nur einen Namespace, der global ist. Und es gibt keine Swift-Header, sodass Sie keine Namen verbergen können.
BEARBEITEN: In Seed 3 wird diese Funktion jetzt im folgenden Sinne online geschaltet: Wenn Ihr Hauptcode MyClass enthält und Ihr Framework MyFramework MyClass enthält, überschattet das erstere standardmäßig das letztere, aber Sie können das im Framework erreichen unter Verwendung der Syntax
MyFramework.MyClass
. Wir haben also tatsächlich die Grundlagen eines bestimmten Namespace!EDIT 2: In Seed 4 haben wir jetzt Zugriffskontrollen! Außerdem habe ich in einer meiner Apps ein eingebettetes Framework und sicher war alles standardmäßig ausgeblendet und ich musste alle Teile der öffentlichen API explizit verfügbar machen. Dies ist eine große Verbesserung.
quelle
Foundation.NSArray
.Während ich damit experimentierte, erstellte ich diese "Namespace" -Klassen in ihren eigenen Dateien, indem ich das Root- "Paket" erweiterte. Ich bin mir nicht sicher, ob dies gegen Best Practices verstößt oder ob es irgendwelche Auswirkungen hat, die mir bewusst sind (?)
AppDelegate.swift
PackageOne.swift
PackageTwo.swift
PackageOneClass.swift
PackageTwoClass.swift
Bearbeiten:
Ich habe gerade herausgefunden, dass das Erstellen von "Unterpaketen" im obigen Code nicht funktioniert, wenn separate Dateien verwendet werden. Vielleicht kann jemand andeuten, warum das so ist?
Hinzufügen der folgenden Dateien zu den oben genannten:
PackageOneSubPackage.swift
PackageOneSubPackageClass.swift
Es wird ein Compilerfehler ausgegeben: 'SubPackage' ist kein Mitgliedstyp von 'PackageOne'.
Wenn ich den Code von PackageOneSubPackageClass.swift nach PackageOneSubPackage.swift verschiebe, funktioniert es. Jemand?
Bearbeiten 2:
Ich habe immer noch damit herumgespielt und herausgefunden (in Xcode 6.1 Beta 2), dass die Pakete durch Definieren in einer Datei in separaten Dateien erweitert werden können:
Hier sind meine Dateien in einem Kern: https://gist.github.com/mikajauhonen/d4b3e517122ad6a132b8
quelle
Ich glaube, dass dies erreicht wird mit:
Dann kann darauf zugegriffen werden mit:
quelle
enum
, kein astruct
, sodass Sie a nicht instanziieren könnenFoo
.Swift verwendet Module ähnlich wie in Python (siehe hier und hier ) und wie @ Kevin Sylvestre vorgeschlagen hat, können Sie die verschachtelten Typen auch als Namespaces verwenden.
Und um die Antwort von @Daniel A. White zu erweitern, sprachen sie im WWDC schnell über die Module.
Auch hier wird erklärt:
quelle
Sie müssen keine Präfixe und Unterklassen wie folgt erstellen:
Mach es so:
Warum? . Denn was Sie deklariert haben, wird im aktuellen Modul deklariert , das Ihr aktuelles Ziel ist . Und
UICollectionViewController
vonUIKit
wird imUIKit
Modul deklariert .Wie verwende ich es im aktuellen Modul?
Wie kann man sie von einem anderen Modul unterscheiden?
quelle
Sie können
extension
den genanntenstruct
s-Ansatz für den Namespace verwenden, ohne den gesamten Code nach rechts einrücken zu müssen. Ich habe mit diesem ein wenig Spielerei gewesen , und ich bin nicht sicher , würde ich so weit wie die Schaffung gehenControllers
undViews
Namensräume wie im Beispiel unten, aber es funktioniert zeigen , wie weit es gehen kann:Profiles.swift :
Profile / ViewControllers / Edit.swift
Profile / Ansichten / Edit.swift
Ich habe dies nicht in einer App verwendet, da ich diese Trennungsstufe noch nicht benötigt habe, aber ich denke, es ist eine interessante Idee. Dadurch sind keine Klassensuffixe wie das allgegenwärtige * ViewController-Suffix mehr erforderlich, das ärgerlich lang ist.
Es verkürzt jedoch nichts, wenn darauf verwiesen wird, wie in Methodenparametern wie diesen:
quelle
Falls jemand neugierig war, ist dies ab dem 10. Juni 2014 ein bekannter Fehler in Swift:
Von SevenTenEleven
"Bekannter Fehler, sorry! Rdar: // problem / 17127940 Das Qualifizieren von Swift-Typen anhand ihres Modulnamens funktioniert nicht."
quelle