8 ответов:
ответ Семнадцать семь на форум Apple dev:
пространства имен не для каждого файла; они для каждой цели (на основе Настройка сборки "имя модуля продукта"). Так что вы бы в конечном итоге с чем-то вот так:
import FrameworkA import FrameworkB FrameworkA.foo()все объявления Swift считаются частью какой-либо модуль, так что даже когда вы говорите:"
NSLog" (да, он все еще существует) вы получаете то, что Свифт думает как "Foundation.NSLog".и Крис Lattner написал в твиттере о пространстве имен.
пространство имен неявно в Swift, все классы (etc) неявно область действия модуля (цель XCode), в котором они находятся. нет префиксов классов нужно
кажется, очень отличается то, что я думал.
Я бы описал пространство имен Swift как желательное; ему было дано много рекламы, которая не соответствует какой-либо значимой реальности на земле.
do конфликт, в том смысле, что ваш собственный код MyClass выигрывает, и вы не можете указать "Нет Нет, я имею в виду MyClass в рамках" - говоритTheFramework.MyClassне работает (компилятор знает, что вы имеете в виду, но он говорит, что не может найти такой класс в рамках).мой опыт заключается в том, что Swift поэтому не имеет пространства имен ни в малейшей степени. Превратив одно из моих приложений из Objective-C в Swift, я создал встроенную структуру, потому что это было так легко и круто сделать. Импорт фреймворка, однако, импортирует все быстрые вещи в фреймворке-так престо, еще раз есть только одно пространство имен, и это глобально. И нет быстрых заголовков, поэтому вы не можете скрыть никаких имен.
EDIT: в seed 3 Эта функция теперь начинает работать в следующем смысле: если ваш основной код содержит MyClass, а ваш фреймворк MyFramework содержит MyClass, первый по умолчанию затмевает последний, но вы можете достичь его в фреймворке с помощью синтаксиса
MyFramework.MyClass. Таким образом, мы действительно имеем зачатки отличное пространство имен!EDIT 2: в seed 4, Теперь у нас есть контроль доступа! Кроме того, в одном из моих приложений у меня есть встроенный фреймворк и, конечно же, все было скрыто по умолчанию, и мне пришлось явно выставить все биты публичного API. Это большое улучшение.
при выполнении некоторых экспериментов с этим я закончил тем, что создал эти классы " namespaced "в своих собственных файлах, расширив корневой"пакет". Не уверен, что это противоречит лучшим практикам или если это имеет какие-либо последствия, я не знаю из(?)
AppDelegate.Свифт
var n1 = PackageOne.Class(name: "Package 1 class") var n2 = PackageTwo.Class(name: "Package 2 class") println("Name 1: \(n1.name)") println("Name 2: \(n2.name)")PackageOne.Свифт
import Foundation struct PackageOne { }PackageTwo.Свифт
import Foundation struct PackageTwo { }PackageOneClass.Свифт
extension PackageOne { class Class { var name: String init(name:String) { self.name = name } } }PackageTwoClass.Свифт
extension PackageTwo { class Class { var name: String init(name:String) { self.name = name } } }
Edit:
только что узнал, что создание "подпакетов" в приведенном выше коде не будет работать при использовании отдельных файлов. Может быть, кто-то может намекнуть на то, почему это было бы дело?
добавление следующих файлов выше:
PackageOneSubPackage.Свифт
import Foundation extension PackageOne { struct SubPackage { } }PackageOneSubPackageClass.Свифт
extension PackageOne.SubPackage { class Class { var name: String init(name:String) { self.name = name } } }его бросает ошибка компилятора: 'SubPackage' не является членом типа 'PackageOne'
если я перемещаю код из PackageOneSubPackageClass.Свифт к Пакагеонесубпакаге.Свифт это работает. Кто?
Edit 2:
возиться с этим еще и выяснил (в Xcode 6.1 beta 2) , что путем определения пакетов в одном файле они могут быть расширены в отдельные файлы:
public struct Package { public struct SubPackage { public struct SubPackageOne { } public struct SubPackageTwo { } } }вот мои файлы в суть: https://gist.github.com/mikajauhonen/d4b3e517122ad6a132b8
Я считаю, что это достигается через:
struct Foo { class Bar { } }тогда он может быть доступен с помощью:
var dds = Foo.Bar();
Swift использует модули так же, как в python (см. здесь и здесь) и как @ Kevin Sylvestre предложил вы также можете использовать вложенные типы как пространства имен.
и чтобы расширить ответ от @Daniel A. White, В WWDC они говорили о модулях в swift.
и здесь это объяснил:
выводимые типы делают код более чистым и менее подверженным ошибкам, в то время как модули исключают заголовки и предоставляют пространства имен.
Если кому-то любопытно, по состоянию на 10 июня 2014 года, это известная ошибка в Swift:
с Семнадцать семь
"известная ошибка, извините! rdar: / / problem / 17127940 квалификация типов Swift по имени их модуля не работает."
пространства имен полезны, когда вам нужно определить класс с помощью тот же имя как класс в существующей структуре.
предположим, что ваше приложение имеет
MyAppимя, и вам нужно объявить свой пользовательскийUICollectionViewController.вы не нужно для префикса и подкласса, как это:
class MAUICollectionViewController: UICollectionViewController {}сделать это, как это:
class UICollectionViewController {} //no error "invalid redeclaration o..."почему?. Потому что то, что вы объявили, объявлено в модуль, который является вашим цель. И
UICollectionViewControllerСUIKitобъявляется вUIKitмодуль.как использовать его в текущем модуле?
var customController = UICollectionViewController() //your custom class var uikitController = UIKit.UICollectionViewController() //class from UIKitкак отличить их от другого модуля?
var customController = MyApp.UICollectionViewController() //your custom class var uikitController = UIKit.UICollectionViewController() //class from UIKit
можно использовать
extensionиспользовать указанныйstructs подход для пространства имен без необходимости отступа всего кода вправо. Я играл с этим немного, и я не уверен, что зашел бы так далеко, как созданиеControllersиViewsпространства имен, как в примере ниже, но это иллюстрирует, как далеко он может вперед:профили.Свифт:
// Define the namespaces struct Profiles { struct Views {} struct ViewControllers {} }Профили / ViewControllers / Edit.Свифт
// Define your new class within its namespace extension Profiles.ViewControllers { class Edit: UIViewController {} } // Extend your new class to avoid the extra whitespace on the left extension Profiles.ViewControllers.Edit { override func viewDidLoad() { // Do some stuff } }Профили/Вид/Редактирование.Свифт
extension Profiles.Views { class Edit: UIView {} } extension Profiles.Views.Edit { override func drawRect(rect: CGRect) { // Do some stuff } }Я не использовал это в приложении, так как мне еще не нужен этот уровень разделения, но я думаю, что это интересная идея. Это устраняет необходимость в четных суффиксах классов, таких как вездесущий суффикс *ViewController, который раздражающе длинный.
однако он ничего не сокращает, когда на него ссылаются, например, в параметрах метода, таких как:
class MyClass { func doSomethingWith(viewController: Profiles.ViewControllers.Edit) { // secret sauce } }
Comments