Простір імен (програмування)

Простір імен(англ. namespace ) — деяка множина, під якою мається на увазі модель, абстрактне сховище або оточення, створене для логічного угрупування унікальних ідентифікаторів (тобто імен).

Ідентифікатор, визначений у просторі імен, асоціюється із цим простором. Один і той самий ідентифікатор може бути незалежно визначений у кількох просторах. Таким чином, значення, пов'язане з ідентифікатором, визначеним в одному просторі імен, може мати (або не мати) таке ж значення, як і такий самий ідентифікатор, визначений в іншому просторі. Мови з підтримкою просторів імен визначають правила, що вказують, якого простору імен належить ідентифікатор (тобто його визначення).

Наприклад, Андрій працює в компанії X, а Identifier - ідентифікатор) його як працівника дорівнює 123. Олег працює в компанії Y, а його ID також дорівнює 123. Єдине (з точки зору якоїсь системи обліку), завдяки чому Андрій та Олег можуть бути помітні при збігаються ID, це їхня приналежність до різних компаній. Відмінність компаній у цьому випадку є системою різних просторів імен (одна компанія — один простір). Наявність двох працівників у компанії з однаковими ID представляє великі проблеми при їх використанні, наприклад, по платіжному чеку, в якому буде вказано працівника з ID 123, буде важко визначити працівника, якому цей чек призначається.

У великих базах даних можуть існувати сотні та тисячі ідентифікаторів. Простір імен (або подібні структури) реалізують механізм для приховування локальних ідентифікаторів. Їх зміст полягає у угрупуванні логічно пов'язаних ідентифікаторів у відповідних просторах імен, таким чином роблячи системумодульної. Обмеження видимості змінних може проводитися шляхом завдання класу її пам'яті.

Операційні системи, багато сучасних мов програмування забезпечують підтримку своєї моделі просторів імен: використовують каталоги (або папки) як модель простору імен. Це дозволяє існувати двом файлам з однаковими іменами (поки вони знаходяться у різних каталогах). У деяких мовах програмування (наприклад C++, Python) ідентифікатори імен просторів самі асоційовані з відповідними просторами. Тому в цих мовах простору імен можуть вкладатись один в одного, формуючи дерево просторів імен. Корінь такого дерева називається глобальним простором імен.

Зміст

У мовах програмування одним із способів завдання межі простору імен може бути використання т.з.області видимості.

Простір імен визначається блоком інструкцій:

Усередині цього блоку ідентифікатори можуть викликатись саме так, як вони були оголошені. Але поза блоком потрібно вказати ім'я простору імен перед ідентифікатором. Наприклад, поза namespace foo ідентифікатор bar повинен бути вказаний як foo::bar . C++ містить деякі інші конструкції, які роблять подібні вимоги необов'язковими. Так, при додаванні рядка

код, вказувати префікс foo:: більше не потрібно. Ще приклад:

Код, не оголошений явно у просторі імен, мається на увазі оголошеним у глобальному просторі імен.

Дозвіл просторів імен C++ ієрархічно. Це означає, що в гіпотетичному просторі імен їжа::суп, ідентифікатор курка позначатиме їжа::суп::курка (якщо простір існує). Якщо не існує, то тоді він вказує на їжу: курка (якщо цей простір існує). Якщоі цей простір не існує, то курка посилається на ідентифікатор у глобальному просторі.

Найчастіше простір імен в C++ використовуються для уникнення колізій імен

Не можна здійснити доступ із однієї одиниці трансляції до члена анонімного простору імен із іншої одиниці.

Хоча простору імен широко використовуються в сучасному коді, більшість старого коду не має подібних можливостей. Наприклад, вся стандартна бібліотека мови C++ визначена всередині namespace std, але до стандартизації багато компонентів спочатку було визначено у глобальному просторі.

Також можна зробити видимим не весь простір, а окремі імена всередині нього, наприклад:

Ідея просторів імен втілена у Java-пакетах. Весь код визначений усередині пакета, причому цей пакет не потребує явно заданого імені. Код інших пакетів доступний при префіксному вказівці імені пакета перед відповідним ідентифікатором, наприклад, клас String в пакеті java.lang може бути викликаний як java.lang.String (цей спосіб відомий як повне ім'я класу). Як і C++, Java пропонує конструкцію, що робить необов'язковим вказівку ім'я пакета ( import ). Проте деякі особливості (як, наприклад, відбиток) вимагають від програміста використання повного імені.

На відміну від C++, простори імен Java не є ієрархічно впорядкованими через синтаксис самої мови. Тим не менш, пакети називаються в ієрархічному стилі. Наприклад, всі пакети, що починаються з java, є частиною платформи Java - пакет java.lang містить базові класи мови, а java.lang.reflect містить базові класи, специфічні для відображення (рефлексії).

Область видимості

Функція та клас можуть бути визначені як неявний простір імен, складнопов'язане з видимістю, доступністю та періодом життя об'єкта.

У мові C# є простори імен, вживання аналогічно C++.

У Python ідея просторів імен реалізована у модулях. (Так само, як і в пакетах Java)

Незважаючи на відсутність формальної підтримки просторів імен, їх легко реалізувати за допомогою об'єктної концепції мови:

У XML специфікація просторів XML імен визначає унікальність імен елементів та атрибутів у документі, аналогічно ролі просторів імен у мові програмування. За допомогою просторів імен XML-документи можуть містити імена елементів або атрибутів більш ніж з одного словника XML.

xmlns (XML Namespace) – простір імен XML. Підключаються RDF (для створення документа RDF), FOAF та RDF Schema (формат оформлення RDF).

FOAF - це теж простір RDF документа, тому перевіряється його оформлення відповідно до словника (правил, специфікації) RDF.

Починаючи з версії 5.3.0, у PHP введено поняття простору імен.

Важливий момент. Директива namespace має бути першим рядком коду у файлі. Виняток становить ключове слово declare, яке може передувати директиві namespace. Не допускається навіть виведення HTML перед першою конструкцією [1] .

Common Lisp

У стандартному синтаксисі Common Lisp є табличні простір імен, що реалізуються через систему пакетів [2] . Для використання ідентифікатора (символу) необхідно вказати його повну назву: назву пакета, двокрапку та назву самого символу [3] .

У Allegro Common Lisp реалізовано нестандартне розширення Common Lisp - ієрархічні простори імен, в якому пакети розділяються точкою в стилі Java, а ідентифікатор від пакетів відокремлюється двокрапкою. Також можливі звернення до суміжних вузлів уієрархії просторів імен за допомогою вказівки відносних шляхів через дві точки [4] . Простори імен Common Lisp є динамічними — вони створюються, наповнюються і знищуються під час виконання програми [джерело?], хоча переважно застосовується декларативна форма їх опису за допомогою форми defpackage [5] .

У PureBasic 5.20 була введена підтримка простору імен, реалізована у вигляді модулів. Простір імен визначається блоком команд Module і EndModule і залежить від розташування вихідних файлах. Це означає, що в одному файлі можуть бути кілька модулів, або навпаки - код модуля може бути розділений на кілька файлів. За умовчанням, весь простір модуля прихований і щоб зробити видимим окремі його елементи, їх необхідно оголосити у спеціальному блоці команд DeclareModule/EndDeclareModule. Все, що не оголошено в цьому блоці, не доступне за межами модуля, і спроба доступу призведе до повідомлення компілятора про порушення прав доступу.

Для доступу до елементів модуля з іншого модуля або глобального простору необхідно вказати ім'я модуля та його елемент, наприклад: Count::x. Також можна використовувати команду UseModule, яка дозволяє відобразити всі видимі елементи модуля у поточний простір. Її дію скасовує команда UnuseModule. Потрібно відзначити, що одночасно можна відобразити видимі елементи кількох модулів, за умови що при цьому не виникне конфлікту імен. Припустимо, що в проекті є модулі з іменами x, y і z.

Цей приклад показує, що можна відобразити в поточний простір кілька модулів, а так само те, що не важлива послідовність відображення елементів модулів та його скасування.

У мовах програмування без підтримки просторів імен простору можутьемулюватись розширенням, використовуючи угоди про найменування ідентифікаторів. Наприклад, бібліотеки мови Сі, такі як Libpng, часто використовують фіксований префікс для всіх функцій та змінних, що є частиною їхнього зовнішнього інтерфейсу. Libpng підтримує зовнішні ідентифікатори, такі як:

png_create_write_struct png_get_signature png_read_row png_set_invalid

Це дає обґрунтовану гарантію того, що ідентифікатори будуть унікальними і таким чином можуть бути використані у великих програмах без побоювання колізії імен ідентифікаторів.

До недоліків емуляції просторів імен можна віднести [джерело не вказано 1973 дня] :

  • відсутність нормального обліку вкладених просторів; ідентифікатори стають надто довгими.
  • Програмісти чи організації можуть використовувати різко несумісні угоди про найменування, цим потенційно провокуючи велику заплутаність.
  • Складні операції або операції запиту над групами ідентифікаторів, що ґрунтуються на просторах імен, в яких вони оголошені, обробляються надто неоптимально або взагалі нездійсненні.
  • Усі виклики ідентифікаторів мають насправді здійснювати з повним ім'ям просторів (англ.) українців. . Мови з безпосередньою підтримкою просторів імен зазвичай надають програмісту можливість попередньо оголошувати, що вони хочуть використовувати деякі (а то й усі) ідентифікатори у програмі тільки з одного простору, які вони згодом можуть використовувати без вказівки на належність до простору.