В документации упоминаются только вложенные типы, но не ясно, могут ли они использоваться в качестве пространств имен. Я не нашел явного упоминания о пространствах имен.
Быстрый поиск по Ctrl-F в их iBook не показывает экземпляров пространств имен ... так что я пойду без?
Джастин Нисснер
1
Я не знаю, почему этот вопрос закрыт. Я увидел пространство имен на лейтмотиве слева от значка Swift, и до сих пор не могу найти упоминаний в документации ...
eonil
Я не смог найти никакой информации по этому вопросу, Google привел меня к этому вопросу :). Возможно, одна из сессий WWDC будет пролить немного света на это.
Zyphrax
Я также жду, когда кто-нибудь из WWDC придет с хорошим объяснением.
Эонил
Эонил ответ правильный. Вы используете модули в XCode для разделения ваших классов.
Пространства имен не для каждого файла; они для каждой цели (в зависимости от настройки сборки «Product Module Name»). Таким образом, вы получите что-то вроде этого:
importFrameworkAimportFrameworkBFrameworkA.foo()
Все объявления Swift считаются частью некоторого модуля, поэтому даже когда вы говорите « NSLog» (да, он все еще существует), вы получаете то, что Swift считает « Foundation.NSLog».
Форумы Apple Dev ... Я видел там столько поворотов, что вы не поверите!
Николас Миари
1
Ссылка на форумы разработчиков Apple разорвана, и Apple forums.developer.apple.com, к сожалению, не импортировала эту ветку на новый форум.
Дай
2
@Dai Похоже, именно поэтому мы должны избегать форумов Apple по вопросам и ответам ... Но члены основной команды разработчиков, похоже, не слишком заботятся о SO. Какая трагедия
Эонил
1
что ты имеешь в виду под камышом?
Александр Миллс
148
Я бы назвал пространство имен Свифта желательным; было дано много рекламы, которая не соответствует какой-либо значимой реальности на местах.
Например, в видеороликах WWDC говорится, что если импортируемая среда имеет класс MyClass, а ваш код имеет класс MyClass, эти имена не конфликтуют, поскольку «искажение имен» дает им разные внутренние имена. В действительности, однако, они делают конфликт, в том смысле , что MyClass выигрывает свой собственный код, и вы не можете указать «Нет , нет, я имею в виду MyClass в рамках» - мол TheFramework.MyClassне работает (компилятор знает , что вы имеете в виду , но он говорит, что не может найти такой класс в рамках).
По моему опыту, Свифт, таким образом, не имеет ни малейшего пространства имен. Превратив одно из моих приложений из Objective-C в Swift, я создал встроенный фреймворк, потому что это было так легко и круто сделать. Однако при импорте фреймворка импортируются все элементы Swift в фреймворке - поэтому, прежде всего, снова существует только одно пространство имен, и оно глобально. И нет заголовков Swift, поэтому вы не можете скрыть имена.
РЕДАКТИРОВАТЬ: В начальном варианте 3 эта функция теперь начинает работать в сети, в следующем смысле: если ваш основной код содержит MyClass, а ваша инфраструктура MyFramework содержит MyClass, первый по умолчанию затмевает последний, но вы можете получить доступ к таковому в рамках используя синтаксис MyFramework.MyClass. Таким образом, у нас действительно есть зачатки отдельного пространства имен!
РЕДАКТИРОВАТЬ 2: В семени 4, у нас теперь есть контроль доступа! Кроме того, в одном из моих приложений у меня есть встроенная инфраструктура, и, конечно же, все было скрыто по умолчанию, и мне пришлось явным образом раскрыть все биты открытого API. Это большое улучшение.
Спасибо за этот ответ. Он работает не только с Frameworks, но и со стандартной библиотекой. Вы можете «перезаписать» массив, например. Тогда «Массив» относится к вашему собственному пользовательскому классу «Массив», а массив стандартной библиотеки доступен как «Swift.Array».
Джордж
3
@ Джордж И так же для NSArray; если вы омрачаете это, вы все равно можете обратиться к нему как Foundation.NSArray.
Мэтт
1
Таким образом, без необходимости разбираться с историей мысли о пространствах имен в бета-версиях: где сейчас находится этот ответ?
Дэн Розенстарк
1
@ Яр, как указано в редакции. Имя модуля является необязательным пространством имен, если существует неоднозначность, и теперь существует конфиденциальность, поэтому имена модулей скрыты, если они не отображаются, и имя может быть ограничено файлом.
Мэтт
2
Это беспокоило меня долгое время, и кажется, что ни один из проектов Swift не должен использовать префикс из-за того, что утверждает Apple, однако в настоящее время префикс все еще требуется, даже с модификаторами доступа. Хотя вы не будете конфликтовать с пакетными или закрытыми классами в среде Apple, чем-либо объявленным общедоступным, например, String, если вы объявите это снова, или любым новым классом, он в конечном итоге будет использовать ваш, если, конечно, вы не привыкли ссылаясь на все классы с его пространством имен .... не хорошо IMO.
Оскар Гомес
19
Проводя некоторые эксперименты с этим, я в итоге создал эти классы «пространства имен» в своих собственных файлах, расширив корневой «пакет». Не уверен, что это противоречит передовому опыту или имеет какие-либо последствия, о которых я не знаю (?)
extensionPackageOne{classClass{var name:Stringinit(name:String){self.name = name
}}}
PackageTwoClass.swift
extensionPackageTwo{classClass{var name:Stringinit(name:String){self.name = name
}}}
Редактировать:
Просто обнаружил, что создание «подпакетов» в приведенном выше коде не будет работать, если использовать отдельные файлы. Может быть, кто-то может намекнуть, почему это так?
Не уверен, что вы имеете в виду под «тестированием», но я пошел дальше и начал создавать свое приложение, используя вышеописанную технику, и, похоже, до сих пор оно хорошо работало с предупреждением, которое я добавил к моей записи выше. Я делаю это главным образом потому, что я привык организовывать свой код таким образом на других языках и был бы благодарен, если бы кто-то с большим знанием мог сказать мне, что это плохая идея, пока я не зайду слишком далеко! :)
bWlrYWphdWhvbmVu
1
продолжать ... это то, что мы хотим ... чтобы иметь возможность иметь один и тот же класс имен в двух разных пакетах, чтобы иметь возможность существовать и ссылаться соответственно (более важно, на разные файлы), и если он не работает, весь идея пространства имен - это провальная идея ...
user2727195
Какие-нибудь побочные эффекты, использующие "struct" как способ взломать пространства имен?
Алекс Ноласко
Не то чтобы я сталкивался с такими характеристиками. Xcode (6.1 GM) в некоторых редких случаях жалуется на несуществующие типы, но я полагаю, что это может быть в том случае, если не структурировать подобный код. Недавно я решил одну проблему, добавив все файлы к моей цели тестирования, которые не имеют никакого смысла, но это решило проблему. :)
Я все еще не так доволен тем, как создаются пространства имен ... что, если у меня есть десять различных классов в пространстве имен, и, кроме того, я предпочитаю хранить классы в их отдельных файлах, не хочу раздувать один файл / структура со всеми классами, любые предложения Кевина.
user2727195
2
Интересно, почему они не думали включать пакеты, это то, что нам нужно, а не пространства имен, я имею в виду, посмотрите на другие языки высокого уровня, такие как Java, C #, ActionScript, у них всех есть пакеты, пространства имен в этом контексте ничем не отличается от использования NS или другие префиксы для классов вашего проекта
user2727195
1
Не могу понять, может ли использование структур как способа взломать пространства имен вызвать неизвестные проблемы.
Алекс Ноласко
1
Это хороший обходной путь для этого. Я попытался использовать этот подход, но должен был немедленно остановиться. Когда я попытался создать пространство имен для классов, связанных с моим представлением (скажем, CustomTableViewCell), автозаполнение в конструкторе интерфейса не предлагало этого. Мне пришлось бы вручную скопировать и вставить имя класса для представления, если бы я использовал этот подход.
ArG
1
Обычно вы используете enum, а не a struct, поэтому вы не можете создать экземпляр Foo.
Кевин
7
Swift использует модули, очень похожие на python (см. Здесь и здесь ), и, как предложил @Kevin Sylvestre, вы также можете использовать вложенные типы в качестве пространств имен.
И чтобы расширить ответ от @Daniel A. White, в WWDC они быстро говорили о модулях.
Я ищу пакеты, подобные конструкции, как упомянуто во второй ссылке 6.4. Пакеты (Python), пространства имен как вложенные типы не могут зайти слишком далеко, что если у меня есть 10 разных классов и в разных файлах в пространстве имен или, скажем, пакет ???
user2727195
7
Пространства имен полезны, когда вам нужно определить класс с тем же именем, что и класс в существующей среде.
Предположим, у вашего приложения есть MyAppимя, и вам нужно объявить свой кастом UICollectionViewController.
Зачем? , Потому что то, что вы объявили, объявлено в текущем модуле , который является вашей текущей целью . И 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использовать упомянутый structподход к пространству имен без необходимости сдвигать весь ваш код вправо. Я играл с этим немного , и я не уверен , что я бы пойти так далеко , как создание Controllersи Viewsпространств имен , как в приведенном ниже примере, но он иллюстрирует , насколько далеко он может пойти:
Profiles.swift :
// Define the namespaces
structProfiles{structViews{}structViewControllers{}}
Профили / 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
}}
Профили / просмотров / Edit.swift
extensionProfiles.Views{classEdit:UIView{}}extensionProfiles.Views.Edit{overridefunc drawRect(rect:CGRect){// Do some stuff
}}
Я не использовал это в приложении, так как мне еще не нужен этот уровень разделения, но я думаю, что это интересная идея. Это устраняет необходимость в четных суффиксах классов, таких как вездесущий суффикс * ViewController, который раздражающе длинный.
Тем не менее, он ничего не сокращает, когда на него ссылаются, например, в параметрах метода, подобных этому:
Ответы:
Ответ от SevenTenEleven на форуме разработчиков Apple :
Также Крис Латтнер написал в Твиттере о пространстве имен .
Кажется, что это совсем не то, о чем я думал.
источник
forums.developer.apple.com
, к сожалению, не импортировала эту ветку на новый форум.Я бы назвал пространство имен Свифта желательным; было дано много рекламы, которая не соответствует какой-либо значимой реальности на местах.
Например, в видеороликах WWDC говорится, что если импортируемая среда имеет класс MyClass, а ваш код имеет класс MyClass, эти имена не конфликтуют, поскольку «искажение имен» дает им разные внутренние имена. В действительности, однако, они делают конфликт, в том смысле , что MyClass выигрывает свой собственный код, и вы не можете указать «Нет , нет, я имею в виду MyClass в рамках» - мол
TheFramework.MyClass
не работает (компилятор знает , что вы имеете в виду , но он говорит, что не может найти такой класс в рамках).По моему опыту, Свифт, таким образом, не имеет ни малейшего пространства имен. Превратив одно из моих приложений из Objective-C в Swift, я создал встроенный фреймворк, потому что это было так легко и круто сделать. Однако при импорте фреймворка импортируются все элементы Swift в фреймворке - поэтому, прежде всего, снова существует только одно пространство имен, и оно глобально. И нет заголовков Swift, поэтому вы не можете скрыть имена.
РЕДАКТИРОВАТЬ: В начальном варианте 3 эта функция теперь начинает работать в сети, в следующем смысле: если ваш основной код содержит MyClass, а ваша инфраструктура MyFramework содержит MyClass, первый по умолчанию затмевает последний, но вы можете получить доступ к таковому в рамках используя синтаксис
MyFramework.MyClass
. Таким образом, у нас действительно есть зачатки отдельного пространства имен!РЕДАКТИРОВАТЬ 2: В семени 4, у нас теперь есть контроль доступа! Кроме того, в одном из моих приложений у меня есть встроенная инфраструктура, и, конечно же, все было скрыто по умолчанию, и мне пришлось явным образом раскрыть все биты открытого API. Это большое улучшение.
источник
Foundation.NSArray
.Проводя некоторые эксперименты с этим, я в итоге создал эти классы «пространства имен» в своих собственных файлах, расширив корневой «пакет». Не уверен, что это противоречит передовому опыту или имеет какие-либо последствия, о которых я не знаю (?)
AppDelegate.swift
PackageOne.swift
PackageTwo.swift
PackageOneClass.swift
PackageTwoClass.swift
Редактировать:
Просто обнаружил, что создание «подпакетов» в приведенном выше коде не будет работать, если использовать отдельные файлы. Может быть, кто-то может намекнуть, почему это так?
Добавляем следующие файлы к вышеуказанному:
PackageOneSubPackage.swift
PackageOneSubPackageClass.swift
Выдает ошибку компилятора: SubPackage не является типом элемента PackageOne.
Если я перенесу код из PackageOneSubPackageClass.swift в PackageOneSubPackage.swift, он будет работать. Кто угодно?
Изменить 2:
Поигравшись с этим еще и выяснив (в Xcode 6.1 beta 2), что, определяя пакеты в одном файле, их можно расширять в отдельные файлы:
Вот мои файлы в гист: https://gist.github.com/mikajauhonen/d4b3e517122ad6a132b8
источник
Я считаю, что это достигается с помощью:
Тогда к нему можно получить доступ используя:
источник
enum
, а не astruct
, поэтому вы не можете создать экземплярFoo
.Swift использует модули, очень похожие на python (см. Здесь и здесь ), и, как предложил @Kevin Sylvestre, вы также можете использовать вложенные типы в качестве пространств имен.
И чтобы расширить ответ от @Daniel A. White, в WWDC они быстро говорили о модулях.
Также здесь объясняется:
источник
Вам не нужно префикс и подкласс, как это:
Делай это так:
Зачем? , Потому что то, что вы объявили, объявлено в текущем модуле , который является вашей текущей целью . И
UICollectionViewController
изUIKit
объявлен вUIKit
модуле.Как использовать его в текущем модуле?
Как отличить их от другого модуля?
источник
Вы можете
extension
использовать упомянутыйstruct
подход к пространству имен без необходимости сдвигать весь ваш код вправо. Я играл с этим немного , и я не уверен , что я бы пойти так далеко , как созданиеControllers
иViews
пространств имен , как в приведенном ниже примере, но он иллюстрирует , насколько далеко он может пойти:Profiles.swift :
Профили / ViewControllers / Edit.swift
Профили / просмотров / Edit.swift
Я не использовал это в приложении, так как мне еще не нужен этот уровень разделения, но я думаю, что это интересная идея. Это устраняет необходимость в четных суффиксах классов, таких как вездесущий суффикс * ViewController, который раздражающе длинный.
Тем не менее, он ничего не сокращает, когда на него ссылаются, например, в параметрах метода, подобных этому:
источник
Если кому-то стало интересно, по состоянию на 10 июня 2014 года это известная ошибка в Swift:
От семидесятидесяти
«Известная ошибка, извините! Rdar: // problem / 17127940 Квалификация типов Swift по имени модуля не работает».
источник