что такое пространство имен в программировании

Пространство имён в программировании

В больших базах данных могут существовать сотни и тысячи идентификаторов. Пространства имён (или схожие структуры) реализуют механизм для сокрытия локальных идентификаторов. Их смысл заключается в группировке логически связанных идентификаторов в соответствующих пространствах имён, таким образом делая систему модульной.

Операционные системы, многие современные языки программирования обеспечивают поддержку своей модели пространств имён: используют каталоги (или папки) как модель пространства имён. Это позволяет существовать двум файлам с одинаковыми именами (пока они находятся в разных каталогах). В некоторых языках программирования (например, C++, дерево пространств имён. Корень такого дерева называется глобальным пространством имён.

Содержание

Границы

В языках программирования одним из способом задания границы пространства имен может быть использование т.н. области видимости.

Использование в языках

Пространство имён определяется блоком инструкций.

в код, указывать префикс foo:: больше не требуется. Еще пример:

Код, не объявленный явным образом в пространстве имён, подразумевается объявленным в глобальном пространстве имён.

Java-пакеты. Весь код определен внутри пакета, причем этот пакет не нуждается в явно заданном имени. Код из других пакетов доступен при префиксном указании имени пакета перед соответствующим идентификатором, например class String в package java.lang может быть вызван как java.lang.String (данный способ известен как полное имя класса). Как и в C++, Java предлагает конструцию, делающую необязательным указание имя пакета ( import ). Тем не менее, некоторые особенности (как, например, отражение) требуют от программиста использования полного имени.

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

Функция и класс может быть определена как неявное пространство имён, сложно связанное с видимостью, доступностью и периодом жизни объекта.

В Википедии

Идея реализована в виде категоризации (структурирование схожих статей по темам).

Источник

Пространства имен (namespaces) в C++

что такое пространство имен в программировании. Смотреть фото что такое пространство имен в программировании. Смотреть картинку что такое пространство имен в программировании. Картинка про что такое пространство имен в программировании. Фото что такое пространство имен в программировании

Пространство имен в C ++ — это обобщенная область видимости. Его объявление начинается с зарезервированного слова namespace, за которым следует имя по выбору программиста, а затем блок в фигурных скобках. Блок содержит базовые объявления и / или определения объектов, функций и других сущностей C ++.

Рассмотрим следующие два скалярных оператора в глобальной области в следующей программе:

int varId = 5 ;
float varId = 2.3 ;

Попытка скомпилировать эту программу приводит к ошибке компиляции. Есть две переменные с одинаковым именем varId. Хотя это две разные переменные двух разных типов, int и float, компилятор отклоняет два объявления, потому что они имеют одно и то же имя. Следующая программа решает эту проблему, объявляя переменные с одинаковыми именами в двух разных обобщенных областях:

namespace NA
<
int varId = 5 ;
>

namespace NB
<
float varId = 2.3 ;
>

int main ( )
<
cout NA :: varId ‘ \n ‘ ;
cout NB :: varId ‘ \n ‘ ;

Результат выглядит следующим образом:

В этой статье рассматривается основная концепция пространства имен и его использование в языке программирования C ++. Чтобы следовать этой статье, вы должны иметь базовые знания языка C ++. Вы также должны знать область действия C ++, хотя она кратко объясняется в этой статье. Чтобы узнать больше о области действия C ++, найдите фразу «Область действия в C ++» (без кавычек) в поле поиска любой веб-страницы linuxhint.com и нажмите Enter. Это приведет вас к статье, написанной этим автором.

Что такое пространство имен?

Декларативная область — это самая большая часть программы, в которой допустимо имя объекта (переменной). Эта область называется областью действия. Пространство имен в C ++ — это обобщенная область видимости, основной целью которой является разрешение конфликтов имен. Пространство имен имеет базовые объявления и / или определения сущностей.

Глобальное пространство имен и его проблема

Глобальное пространство имен — это глобальная область видимости. Рассмотрим следующую короткую программу:

int ident = 55 ;
float ident = 12.17 ;

В приведенной выше программе есть две переменные, обе называемые идентификатором. Эти переменные находятся в глобальной области видимости; то есть они находятся в глобальном пространстве имен. Попытка скомпилировать эту программу завершится ошибкой. Глобальная область видимости не принимает более одной переменной с одинаковым именем, поэтому существует необходимость в настраиваемом пространстве имен.

Пользовательское пространство имен

namespace NA
<
int varInt = 6 ;
float flt ;
>

namespace NB
<
int varInt = 7 ;
float flt ;
>

int main ( )
<
cout NA :: varInt ‘ \n ‘ ;
cout NB :: varInt ‘ \n ‘ ;
NA :: flt = 2.5 ;
NB :: flt = 4.8 ;
cout NA :: flt ‘ \n ‘ ;
cout NB :: flt ‘ \n ‘ ;

Обратите внимание, что имена NA :: flt и NB :: flt в конечном итоге определены в функции main (). C ++ не допускает такого определения в глобальной области видимости.

Обратите внимание, что настраиваемое пространство имен является вложенным пространством имен для глобального пространства имен.

Директива использования

Чтобы не вводить все время «namepace :: name» вместо просто «name» после объявления пространства имен, вы можете использовать директиву using. Синтаксис использования директивы using следующий:

С помощью директивы не директива препроцессора, поэтому она заканчивается точкой с запятой (;).

Следующая программа иллюстрирует использование директивы using и др.:

namespace NB
<
int varInt = 7 ;
int func ( )
<
return varInt ;
>
>

int fn ( )
<
using namespace NB ;
int myVar2 = func ( ) ;
//other objects and functions from NB follow.
return myVar2 ;
>

int myVar3 = NB :: func ( ) ;

int main ( )
<
cout fn ( ) ‘ ‘ myVar3 ‘ \n ‘ ;

Переменная, объявленная в глобальной области (глобальном пространстве имен), просматривается от точки объявления до конца файла. Это также видно во вложенных пространствах имен (вложенных областях), таких как вложенная область видимости функции fn () выше. С помощью директивы соединяет его пространство имен из позиции, в которой он размещен в конце области, в которой он размещен.

Имя func () из пространства имен NB нельзя увидеть под определением fn (), потому что » using namespace NB;» был помещен в область действия функции (блок). При этом условии, чтобы использовать функцию » func () » вне блока (области) пространства имен NB, ему должен предшествовать » NB :: «, как в следующем операторе:

С помощью директивы присоединяется своим пространством имен с внешним гнездовым пространством именами из положения, в котором он находится на конец внешних вложенности имен. В следующей программе пространство имен NA объединено с глобальным пространством имен. Оба пространства имен затем расширяются в пространство имен определения функции fn (), в котором они объединяются с пространством имен NB. Пространство имен NB заканчивается в конце определения функции fn (), а два предыдущих пространства имен продолжаются до конца файла (считывания кода).

namespace NA
<
int varInt = 6 ;
int func ( )
<
return varInt ;
>

namespace NB
<
int varInt = 7 ;
int func ( )
<
return varInt ;
>
>

using namespace NA ;
int myVar0 = varInt ;
//other objects and functions from :: and NB follow.

int fn ( )
<
int myVar1 = varInt ;
using namespace NB ;
int myVar2 = NB :: func ( ) ;
//other objects and functions from NB follow, till end of this scope.
return myVar1 + myVar2 ;
>

//Only objects and functions from :: and NB follow.

int myVar3 = NB :: func ( ) ;

int main ( )
<
cout myVar0 ‘ ‘ fn ( ) ‘ ‘ myVar3 ‘ \n ‘ ;

На выходе будет 6, 13, 7.

Под утверждением » using namespace NA; «Переменные из глобального пространства имен и пространства имен NA могут использоваться без указания их исходного пространства имен. Следующий оператор использует varInt пространства имен NA. Область объединенного пространства имен global и NA простирается в пространство имен функции fn (). Итак, varInt первого оператора в области видимости функции fn () относится к пространству имен NA.

Поскольку область для глобального пространства имен и пространства имен NA распространяется на всю область видимости fn (), после » int myVar2 = NB :: func ();, «Любое имя из пространства имен NB может использоваться только в области fn () без предшествующего ему» NB :: «, только если оно не встречается в NA и глобальных пространствах имен (блоках). В противном случае ему должно предшествовать » NB :: «. Область объединенных пространств имен для NA и global продолжается ниже определения fn () и в функцию main () до конца файла.

Расширение пространства имен NB начинается с » int myVar2 = NB :: func (); «В блоке fn () и заканчивается в конце блока определения fn ().

Примечание: Пространства имен, регионы которых соединяются, не должны иметь одинаковые имена переменных в разных блоках пространств имен, так как это все равно вызовет конфликт.

Области пространства имен

Пространство имен — это область видимости. Помимо глобального пространства имен (глобальная область видимости), любое пространство имен должно быть объявлено в блоке. Этот блок является первой частью возможных распределенных областей пространства имен. С помощью директивы using пространство имен может быть расширено как регионы в других областях.

Объекты, объявленные в теле пространства имен, называются членами этого пространства имен, а имена, введенные этими объявлениями в декларативную область пространства имен, называются именами членов этого пространства имен.

Вложенные пространства имен

Следующая программа показывает вложенные пространства имен:

namespace A
<
int i = 1 ;
namespace B
<
int i = 2 ;
namespace C
<
int i = 3 ;
>
>
>

int main ( )
<
cout A :: i ‘ ‘ A :: B :: i ‘ ‘ A :: B :: C :: i ‘ \n ‘ ;

Обратите внимание, что доступ к трем значениям был осуществлен с помощью оператора разрешения области видимости.

Стандартное пространство имен

В C ++ есть библиотека, называемая стандартной библиотекой. Имена объектов, функций и других сущностей в этой библиотеке взяты из пространства имен, называемого стандартным пространством имен, записанного как std. Стандартная библиотека содержит подбиблиотеки, и одна из этих подбиблиотек — iostream. Библиотека iostream содержит объект cout, который используется для отправки результатов на консоль (терминал).

Имя cout должно находиться в пространстве имен std. Чтобы использовать iostream с его пространством имен std, программа должна быть следующей:

Обратите внимание на использование директивы using и std. Термин » #include » является директивой препроцессора и не заканчивается точкой с запятой. Он включает в себя «файл» iostream в позиции своей директивы.

Заключение

Пространство имен — это область видимости. Описание (определение) пространства имен содержит базовые объявления и / или определения объектов, функций и других сущностей C ++. Вне определения пространства имен доступ к имени можно получить с помощью синтаксиса » namespaceName :: name «. Помимо глобального пространства имен (глобальная область видимости), любое пространство имен должно быть объявлено в блоке. Этот блок является первой частью возможных распределенных областей пространства имен. С помощью директивы using пространство имен может быть расширено как регионы в других областях. Пространства имен, регионы которых соединяются, не должны иметь одинаковые имена переменных в разных блоках пространств имен, так как это все равно вызовет конфликт имен.

Источник

Пространства имен (C++)

В следующем примере показано объявление пространства имен и продемонстрированы три способа доступа к членам пространства имен из кода за его пределами.

Использование полного имени:

Чтобы добавить в область видимости один идентификатор, используйте объявление using:

Чтобы добавить в область видимости все идентификаторы пространства имен, используйте директиву using:

директивы using

using Директива позволяет использовать все имена в namespace для использования без имени пространства имен в качестве явного квалификатора. Использование директивы using в файле реализации (т. е. *. cpp) при использовании нескольких различных идентификаторов в пространстве имен; Если вы используете только один или два идентификатора, рассмотрите использование объявления using, чтобы привести эти идентификаторы в область, а не все идентификаторы в пространстве имен. Если локальная переменная имеет такое же имя, как и переменная пространства имен, то переменная пространства имен будет скрытой. Создавать переменную пространства имен с те же именем, что и у глобальной переменной, является ошибкой.

Директиву using можно поместить в верхнюю часть CPP-файла (в области видимости файла) или внутрь определения класса или функции.

Без особой необходимости не размещайте директивы using в файлах заголовков (*.h), так как любой файл, содержащий этот заголовок, добавит все идентификаторы пространства имен в область видимости, что может вызвать скрытие или конфликты имен, которые очень трудно отлаживать. В файлах заголовков всегда используйте полные имена. Если эти имена получаются слишком длинными, используйте псевдоним пространства имен для их сокращения. (См. ниже.)

Объявление пространств имен и их членов

Как правило, пространство имен объявляется в файле заголовка. Если реализации функций находятся в отдельном файле, определяйте имена функций полностью, как показано в следующем примере.

Реализации функций в контосодата. cpp должны использовать полное имя, даже если поместить using директиву в начало файла:

Пространство имен может быть объявлено в нескольких блоках в одном файле и в нескольких файлах. Компилятор соединит вместе все части во время предварительной обработки и полученное в результате пространство имен будет содержать все члены, объявленные во всех частях. Примером этого является пространство имен std, которое объявляется в каждом из файлов заголовка в стандартной библиотеке.

Члены именованного пространства имен могут определяться за его границами, если они объявлены путем явной квалификации определяемого пространства имен. Однако определение должно располагаться после точки объявления в пространстве имен, окружающем то пространство имен, где находится объявление. Пример:

Эта ошибка может возникнуть, когда члены пространства имен объявляются в нескольких файлах заголовка и эти заголовки не включены в правильном порядке.

Глобальное пространство имен

Пространство имен std

Вложенные пространства имен

Пространства имен могут быть вложенными. Обычное вложенное пространство имен имеет неполный доступ к членам родительского элемента, но родительские элементы не имеют неполного доступа к вложенному пространству имен (если только оно не объявлено как встроенное), как показано в следующем примере:

Обычные вложенные пространства имен можно использовать для инкапсуляции данных о внутренней реализации, которые не являются частью открытого интерфейса родительского пространства имен.

Встроенные пространства имен (C++ 11)

В отличие от обычных вложенных пространств имен члены встроенного пространства имен обрабатываются как члены родительского пространства имен. Эта особенность позволяет выполнять поиск перегруженных функций с зависимостью от аргументов среди функции, которые имеют перегрузки в родительском и вложенном встроенном пространстве имен. Это также позволяет объявлять специализации в родительском пространстве имен для шаблонов, объявленных во встроенном пространстве имен. В следующем примере показано, как внешний код привязывается к встроенному пространству имен по умолчанию.

В следующем примере показано, как можно объявить специализацию в родительском пространстве имен шаблона, объявленного во встроенном пространстве имен.

Встроенные пространства имен можно использовать как механизм управления версиями для управления изменениями в открытом интерфейсе библиотеки. Например, можно создать одно родительское пространство имен и инкапсулировать каждую версию интерфейса в своем собственном пространстве имен, вложенном в родительское. Пространство имен, которое содержит самую последнюю или основную версию, квалифицируется как встроенное и поэтому представляется так, будто оно является непосредственным членом родительского пространства имен. Клиентский код, вызывающий Parent::Class, автоматически привязывается к новому коду. Клиенты, которые предпочитают использовать старую версию, могут по-прежнему получить доступ к ней, используя полный путь к вложенному пространству имен, содержащему данный код.

Ключевое слово inline должно применяться к первому объявлению пространства имен в единице компиляции.

Псевдонимы пространств имен

Имена пространств имен должны быть уникальными, из-за чего зачастую они получаются не слишком короткими. Если длина имени затрудняет чтение кода или утомительно вводить файл заголовка, где нельзя использовать директивы using, можно создать псевдоним пространства имен, который служит аббревиатурой для фактического имени. Пример:

анонимные или безымянные пространства имен

Вы можете создать явное пространство имен, но не присвоить ему имя.

Это называется безымянным или анонимным пространством имен, и его можно использовать, если нужно сделать объявления переменных невидимыми для кода в других файлах (т. е. обеспечить их внутреннюю компоновку) без создания именованного пространства имен. Весь код, находящийся в том же файле, может видеть идентификаторы в безымянном пространстве имен, но эти идентификаторы, а также само пространство имен, будет невидимым за пределами этого файла или, точнее, вне блока перевода.

Источник

Кое-что о пространстве имён

Так, вот, возвращаясь к теме статьи, могу сказать, что пространство имён — один из очень важных столпов, на которых базируется написание сложных web-приложений группой слабознакомых друг с другом разработчиков.

Было непонятно назначение этой директивы и что именно в ней указывать, если указывать можно было любую строку. Рекомендация от авторов языка использовать в качестве части названия пакета зарегистрированного на тебя (на твою компанию) домена выглядело несколько экстравагантно. Это сейчас каждый-всякий-любой имеет свой собственный домен и такая рекомендация не сильно смущает, а 15-20 лет назад я очень сильно думал, какой домен взять в качестве названия для своего первого пакета и на что это может повлиять в дальнейшем. Только впоследствии, когда я собирал приложения с помощью maven ’а, я оценил прозорливость данной рекомендации.

Менеджеры зависимостей

Понять значение пространства имён мне помогли менеджеры зависимостей. Если твой код использует сторонний, который зависит от других пакетов, зависящих от третьих — в такой свалке очень трудно поддерживать порядок. Тем не менее, именно из-за обратно-доменного правила наименования пакетов в куче JAR’ов, сваленных в один каталог (например, в WEB-INF/lib ), достаточно легко ориентироваться:

что такое пространство имен в программировании. Смотреть фото что такое пространство имен в программировании. Смотреть картинку что такое пространство имен в программировании. Картинка про что такое пространство имен в программировании. Фото что такое пространство имен в программировании

Сравните с npm ( JavaScript ):

что такое пространство имен в программировании. Смотреть фото что такое пространство имен в программировании. Смотреть картинку что такое пространство имен в программировании. Картинка про что такое пространство имен в программировании. Фото что такое пространство имен в программировании

что такое пространство имен в программировании. Смотреть фото что такое пространство имен в программировании. Смотреть картинку что такое пространство имен в программировании. Картинка про что такое пространство имен в программировании. Фото что такое пространство имен в программировании

что даёт некоторое преимущество в навигации по зависимостям перед одноуровневым размещением.

Вот статистика по центральным репозиториям пакетов для Java / JS / PHP :

Скорее всего для maven ’а в статистике учитываются все версии модулей, в то время, как в npm и composer учитываются именно сами модули.

Для чего нужно пространство имён?

Пространство имён по версии Java ( package ) и PHP ( namespace ) прежде всего позволяет однозначно адресовать конкретный элемент кода в совокупной общности. И вот это вот свойство пространства имён (логическая группировка) и даёт возможность создавать более сложные программные комплексы менее связанными друг с другом группами разработчиков.

Адресация программных элементов

В PHP класс \Doctrine\DBAL\Schema\Column адресуется однозначно, каким бы образом не подключался исходный код к проекту. IDE способно без труда сформировать этот адрес. В PhpStorm это делается так (правой кнопкой по элементу кода):

что такое пространство имен в программировании. Смотреть фото что такое пространство имен в программировании. Смотреть картинку что такое пространство имен в программировании. Картинка про что такое пространство имен в программировании. Фото что такое пространство имен в программировании

что такое пространство имен в программировании. Смотреть фото что такое пространство имен в программировании. Смотреть картинку что такое пространство имен в программировании. Картинка про что такое пространство имен в программировании. Фото что такое пространство имен в программировании

Для адресации функции query в документации (переписке, баг-трекере и т.п.) приходится ссылаться на конкретную строку кода в файле:

что такое пространство имен в программировании. Смотреть фото что такое пространство имен в программировании. Смотреть картинку что такое пространство имен в программировании. Картинка про что такое пространство имен в программировании. Фото что такое пространство имен в программировании

Разумеется, при изменении кол-ва строк в файле или перемещении/переименовании файла мы будем иметь в документации устаревший адрес интересующего нас программного элемента.

Таким образом, использование пространства имён позволяет ссылкам на различные элементы кода проекта оставаться актуальными гораздо дольше, чем ссылки на строку в файле.

Обнаружение конфликтующих версий кода

В JS подобного не возникает в силу отсутствия namespace’ов. Я сам сталкивался с ситуацией, когда при установке в Magento дополнительных модулей количество подгружаемых ими различных версий библиотеки jQuery переваливало за 5-6. С одной стороны, подобное поведение даёт бОльшую свободу самим разработчикам, с другой — бОльшая свобода предъявляет и бОльшие требования к квалификации. Ну а поиск ошибок в такой разноверсионной лапше зависимостей — квалификации на порядок-два выше, чем квалификации для создания этих самых ошибок.

Использование namespace’ов в PHP позволяет легко обнаруживать подобные конфликты на уровне IDE (для примера я сделал второй файл с дубликатом класса внутри):

что такое пространство имен в программировании. Смотреть фото что такое пространство имен в программировании. Смотреть картинку что такое пространство имен в программировании. Картинка про что такое пространство имен в программировании. Фото что такое пространство имен в программировании

Таким образом, задача по обнаружению дубликатов элементов кода в проекте становится достаточно легко выполнимой.

Автозагрузка кода

Функция spl_autoload_register в PHP позволяет разработчику не заморачиваться тем, где именно находятся файлы с исходниками его классов. В любом проекте можно переопределить эту функцию и реализовать собственный алгоритм загрузки скриптов по имени класса. Без применения пространства имён приходилось выписывать довольно кучерявые имена для классов, чтобы обеспечить их уникальность в пределах сложного проекта (особенно с учётом сторонних библиотек). В Zend1 абстрактный адаптер для работы с БД определялся таким образом:

Для обеспечения уникальности приходилось, по сути, добавлять namespace в имя класса. Само собой, при использовании таких имён классов в коде приходится шире водить глазами по строкам.

Видно, что исходники в разных библиотеках могут располагаться по различным путям (различные внтуримодульные структуры), а composer при формировании проекта создаёт карту наложения логической иерархии классов на файловую систему. И пространства имён играют в этом наложении значимую роль.

Резюме

В свете вышесказанного я считаю, что языки программирования, нативно использующие пространства имён для структурирования исходного кода при помощи логической группировки его элементов позволяют с меньшими затратами строить более сложные приложения, чем языки, подобной логической группировки не имеющие. Соответственно, максимальная сложность приложений, которые можно создать на Java / PHP / C++ /. не может быть достигнута разработчиками с аналогичной квалификацией на JavaScript / Python / C /.

Источник

Пространство имён (программирование)

Из Википедии — свободной энциклопедии

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

Идентификатор, определённый в пространстве имён, ассоциируется с этим пространством. Один и тот же идентификатор может быть независимо определён в нескольких пространствах. Таким образом, значение, связанное с идентификатором, определённым в одном пространстве имён, может иметь (или не иметь) такое же значение, как и такой же идентификатор, определённый в другом пространстве. Языки с поддержкой пространств имён определяют правила, указывающие, к какому пространству имён принадлежит идентификатор (то есть его определение).

Например, Андрей работает в компании X, а ID (сокр. от англ. Identifier — идентификатор) его как работника равен 123. Олег работает в компании Y, а его ID также равен 123. Единственное (с точки зрения некой системы учёта), благодаря чему Андрей и Олег могут быть различимы при совпадающих ID, это их принадлежность к разным компаниям. Различие компаний в этом случае представляет собой систему различных пространств имён (одна компания — одно пространство). Наличие двух работников в компании с одинаковыми ID представляет большие проблемы при их использовании, например, по платёжному чеку, в котором будет указан работник с ID 123, будет весьма затруднительно определить работника, которому этот чек предназначается.

В больших базах данных могут существовать сотни и тысячи идентификаторов. Пространства имён (или схожие структуры) реализуют механизм для сокрытия локальных идентификаторов. Их смысл заключается в группировке логически связанных идентификаторов в соответствующих пространствах имён, таким образом делая систему модульной. Ограничение видимости переменных может также производиться путём задания класса её памяти.

Операционные системы, многие современные языки программирования обеспечивают поддержку своей модели пространств имён: используют каталоги (или папки) как модель пространства имён. Это позволяет существовать двум файлам с одинаковыми именами (пока они находятся в разных каталогах). В некоторых языках программирования (например, C++, Python) идентификаторы имён пространств сами ассоциированы с соответствующими пространствами. Поэтому в этих языках пространства имён могут вкладываться друг в друга, формируя дерево пространств имён. Корень такого дерева называется глобальным пространством имён.

Источник

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *