В вычислительной технике пространство имен — это набор знаков ( имен ), которые используются для идентификации и ссылки на объекты различных видов. Пространство имен гарантирует, что все объекты заданного набора имеют уникальные имена, чтобы их можно было легко идентифицировать .
Пространства имен обычно структурированы как иерархии, чтобы обеспечить повторное использование имен в различных контекстах. В качестве аналогии рассмотрим систему именования людей , где у каждого человека есть имя, а также фамилия, общая с его родственниками. Если имена членов семьи уникальны только в пределах каждой семьи, то каждого человека можно однозначно идентифицировать по комбинации имени и фамилии; существует только одна Джейн Доу, хотя может быть много Джейн. В пространстве имен семьи Доу достаточно просто «Джейн», чтобы однозначно обозначить этого человека, в то время как в «глобальном» пространстве имен всех людей должно использоваться полное имя.
Яркими примерами пространств имен являются файловые системы , которые назначают имена файлам. [1] Некоторые языки программирования организуют свои переменные и подпрограммы в пространствах имен. [2] [3] [4] Компьютерные сети и распределенные системы назначают имена ресурсам, таким как компьютеры , принтеры , веб-сайты и удаленные файлы. Операционные системы могут разделять ресурсы ядра с помощью изолированных пространств имен для поддержки контейнеров виртуализации .
Аналогично, иерархические файловые системы организуют файлы в каталогах. Каждый каталог представляет собой отдельное пространство имен, так что каталоги "letters" и "invoices" могут оба содержать файл "to_jane".
В компьютерном программировании пространства имен обычно используются для группировки символов и идентификаторов вокруг определенной функциональности, а также для предотвращения конфликтов имен между несколькими идентификаторами, имеющими одно и то же имя.
В сетевых технологиях система доменных имен организует веб-сайты (и другие ресурсы) в иерархические пространства имен .
Имена элементов определяются разработчиком. Это часто приводит к конфликту при попытке смешать XML-документы из разных XML-приложений.
Этот XML содержит информацию HTML-таблицы :
<table> <tr> <td> Яблоки </td> <td> Апельсины </td> </tr> </table>
Этот XML-код содержит информацию о столе (т. е. предмете мебели):
<table> <name> Журнальный столик из красного дерева </name> <width> 80 </width> <length> 120 </length> </table>
Если бы эти фрагменты XML были добавлены вместе, возник бы конфликт имен. Оба содержат <table>...</table>
элемент, но элементы имеют разное содержание и значение.
XML-анализатор не будет знать, как обрабатывать эти различия.
Конфликтов имен в XML можно легко избежать, используя префикс имени.
Следующий XML-код различает информацию о таблице HTML и мебели с помощью префиксов «h» и «f» в начале элементов.
<h:table> <h:tr> <h:td> Яблоки </h:td> <h:td> Апельсины </h:td> </h:tr> </h:table> <f:table> <f:name> Журнальный столик из красного дерева </f:name> <f:width> 80 </f:width> <f:length> 120 </f:length> </f:table>
Имя в пространстве имен состоит из имени пространства имен и локального имени. [5] [6] Имя пространства имен обычно применяется как префикс к локальному имени.
В расширенной форме Бэкуса–Наура :
имя = < имя пространства имен > разделитель < локальное имя >
Когда местные названия используются сами по себе, разрешение имен применяется для определения того, на какое конкретное название (если таковое имеется) ссылается какое-либо конкретное местное название.
Делегирование обязанностей между сторонами важно в реальных приложениях, таких как структура Всемирной паутины. Пространства имен позволяют делегировать назначение идентификаторов нескольким организациям, выпускающим имена, сохраняя при этом глобальную уникальность. [8] Центральный орган регистрации регистрирует назначенные выделенные имена пространств имен . Каждое имя пространства имен выделяется организации, которая впоследствии отвечает за назначение имен в выделенном им пространстве имен. Эта организация может быть организацией, выпускающей имена, которая сама назначает имена , или другим органом регистрации , который далее делегирует части своего пространства имен различным организациям.
Схема именования, которая допускает субделегирование пространств имен третьим лицам, называется иерархическим пространством имен .
Иерархия является рекурсивной, если синтаксис имен пространств имен одинаков для каждого подделегирования. Примером рекурсивной иерархии является система доменных имен .
Примером нерекурсивной иерархии является унифицированное имя ресурса, представляющее номер IANA ( Internet Assigned Numbers Authority ).
Имя пространства имен может предоставлять контекст ( область применения в информатике) имени, и эти термины иногда используются взаимозаменяемо. Однако контекст имени может также предоставляться другими факторами, такими как место, где оно встречается, или синтаксис имени.
Для многих языков программирования пространство имен является контекстом для их идентификаторов . В операционной системе примером пространства имен является каталог. Каждое имя в каталоге уникально идентифицирует один файл или подкаталог. [9]
Как правило, имена в пространстве имен не могут иметь более одного значения; то есть разные значения не могут разделять одно и то же имя в одном и том же пространстве имен. Пространство имен также называется контекстом , потому что одно и то же имя в разных пространствах имен может иметь разные значения, каждое из которых соответствует своему пространству имен.
Ниже приведены другие характеристики пространств имен:
Помимо его абстрактного технического использования языка, описанного выше, некоторые языки имеют определенное ключевое слово, используемое для явного управления пространством имен, среди прочего. Ниже приведен пример пространства имен в C++:
#include <iostream> // Вот как можно перенести имя в текущую область видимости. В данном случае это // перенесение их в глобальную область видимости. using std :: cout ; using std :: endl ; пространство имен box1 { int box_side = 4 ; } пространство имен box2 { int box_side = 12 ; } int main () { int box_side = 42 ; cout << box1 :: box_side << endl ; // Выходы 4. cout << box2 :: box_side << endl ; // Выходы 12. cout << box_side << endl ; // Выходы 42. }
Пространство имен в информатике (иногда также называемое областью действия имени ) — это абстрактный контейнер или среда, созданная для хранения логической группировки уникальных идентификаторов или символов (т. е. имен). Идентификатор, определенный в пространстве имен, связан только с этим пространством имен. Один и тот же идентификатор может быть независимо определен в нескольких пространствах имен. То есть идентификатор, определенный в одном пространстве имен, может иметь или не иметь то же значение, что и тот же идентификатор, определенный в другом пространстве имен. Языки, поддерживающие пространства имен, определяют правила, которые определяют, к какому пространству имен принадлежит идентификатор (а не его определение). [10]
Эту концепцию можно проиллюстрировать с помощью аналогии. Представьте, что две компании, X и Y, назначают своим сотрудникам идентификационные номера. У X не должно быть двух сотрудников с одинаковым идентификационным номером, и то же самое касается Y; но не проблема, если в обеих компаниях используется один и тот же идентификационный номер. Например, если Билл работает в компании X, а Джейн работает в компании Y, то не проблема, если каждый из них будет сотрудником № 123. В этой аналогии идентификационный номер является идентификатором, а компания служит пространством имен. Не возникает проблем, если один и тот же идентификатор идентифицирует разных людей в каждом пространстве имен.
В больших компьютерных программах или документах обычно есть сотни или тысячи идентификаторов. Пространства имен (или аналогичная техника, см. Эмуляция пространств имен) предоставляют механизм для сокрытия локальных идентификаторов. Они предоставляют средства для группировки логически связанных идентификаторов в соответствующие пространства имен, тем самым делая систему более модульной .
Устройства хранения данных и многие современные языки программирования поддерживают пространства имен. Устройства хранения используют каталоги (или папки) в качестве пространств имен. Это позволяет хранить на устройстве два файла с одинаковым именем, если они хранятся в разных каталогах. В некоторых языках программирования (например, C++ , Python ) идентификаторы, именующие пространства имен, сами связаны с включающим пространством имен. Таким образом, в этих языках пространства имен могут быть вложенными, образуя дерево пространств имен . В корне этого дерева находится неименованное глобальное пространство имен .
Начиная с C99 в языке C можно использовать анонимные структуры в качестве пространств имен .
// helper.c static int _add ( int a , int b ) { return a + b ; } const struct { double pi ; int ( * add ) ( int , int ); } helper = { 3.14 , _add }; // helper.h const struct { double pi ; int ( * add ) ( int , int ); } helper ; // main.c #include <stdio.h> #include "helper.h" int main ( ){ printf ( "3 + 2 = %d \ n " , helper.add ( 3 , 2 )); printf ( " пи равно %f \n " , helper.pi ); }
В C++ пространство имен определяется с помощью блока пространства имен. [11]
пространство имен abc { int bar ; }
В этом блоке идентификаторы могут использоваться точно так, как они объявлены. За пределами этого блока спецификатор пространства имен должен быть префиксом. Например, за пределами namespace abc
, bar
необходимо записать, abc::bar
чтобы получить доступ. C++ включает другую конструкцию, которая делает эту многословность ненужной. Добавляя строку
используя пространство имен abc ;
к фрагменту кода префикс abc::
больше не нужен.
Идентификаторы, которые явно не объявлены в пространстве имен, считаются находящимися в глобальном пространстве имен.
int foo ;
Эти идентификаторы могут использоваться точно так, как они объявлены, или, поскольку глобальное пространство имен не имеет имени, спецификатор пространства имен ::
может быть префиксом. Например, foo
также может быть написано ::foo
.
Разрешение пространства имен в C++ иерархично. Это означает, что в гипотетическом пространстве имен food::soup
идентификатор chicken
ссылается на food::soup::chicken
. Если food::soup::chicken
не существует, то ссылается на food::chicken
. Если ни то, food::soup::chicken
ни другое не food::chicken
существует, chicken
ссылается на ::chicken
, идентификатор в глобальном пространстве имен.
Пространства имен в C++ чаще всего используются для избежания конфликтов имен . Хотя пространства имен широко используются в недавнем коде C++, большая часть старого кода не использует эту возможность, поскольку ее не было в ранних версиях языка. Например, вся стандартная библиотека C++ определена в namespace std
, но до стандартизации многие компоненты изначально находились в глобальном пространстве имен. Программист может вставить using
директиву, чтобы обойти требования разрешения пространства имен и получить обратную совместимость со старым кодом, который ожидает, что все идентификаторы будут в глобальном пространстве имен. Однако использование директивы using
по причинам, отличным от обратной совместимости (например, удобство), считается противоречащим хорошей практике написания кода.
В Java идея пространства имен воплощена в пакетах Java . Весь код принадлежит пакету, хотя этот пакет не обязательно должен быть явно назван. Доступ к коду из других пакетов осуществляется путем добавления префикса имени пакета перед соответствующим идентификатором, например, class String
на можно ссылаться как (это известно как полное имя класса ). Как и в C++, в Java есть конструкция, которая делает ненужным ввод имени пакета ( ). Однако некоторые функции (например, отражение ) требуют от программиста использования полного имени.package java.lang
java.lang.String
import
В отличие от C++, пространства имен в Java не являются иерархическими, если говорить о синтаксисе языка. Однако пакеты именуются иерархически. Например, все пакеты, начинающиеся с , java
являются частью платформы Java — пакет java.lang
содержит классы, являющиеся ядром языка, и java.lang.reflect
содержит основные классы, относящиеся конкретно к отражению.
В Java (и Ada , C# и других) пространства имен/пакеты выражают семантические категории кода. Например, в C# namespace System
содержит код, предоставляемый системой ( .NET Framework ). Насколько специфичны эти категории и насколько глубоки иерархии, зависит от языка.
Области действия функций и классов можно рассматривать как неявные пространства имен, которые неразрывно связаны с видимостью, доступностью и временем существования объекта .
Пространства имен широко используются в языке C#. Все классы .NET Framework организованы в пространства имен, чтобы использовать их более четко и избежать хаоса. Кроме того, пользовательские пространства имен широко используются программистами, как для организации своей работы, так и для избежания конфликтов имен . При ссылке на класс следует указать либо его полное имя, что означает пространство имен, за которым следует имя класса,
System.Console.WriteLine ( " Hello World ! " ) ; int i = System.Convert.ToInt32 ( " 123 " ) ;
или добавьте оператор using . Это устраняет необходимость упоминать полное имя всех классов в этом пространстве имен.
с использованием Системы ; Console.WriteLine ( " Привет , мир!" ); int i = Convert.ToInt32 ( "123 " ) ;
В приведенных выше примерах System — это пространство имен, а Console и Convert — это классы, определенные внутри System .
В Python пространства имен определяются отдельными модулями, а поскольку модули могут содержаться в иерархических пакетах, то пространства имен также являются иерархическими. [12] [13] В общем случае, когда модуль импортируется, то имена, определенные в модуле, определяются через пространство имен этого модуля и доступны из вызывающих модулей с использованием полностью квалифицированного имени.
# предположим, что modulea определяет две функции: func1() и func2() и один класс: Class1 import ModuleaМодульa.func1 ( ) Модульa.func2 ( ) a = Модульa.Class1 ( )
Оператор from ... import ...
можно использовать для вставки соответствующих имен непосредственно в пространство имен вызывающего модуля, и к этим именам можно будет получить доступ из вызывающего модуля без квалифицированного имени:
# предположим, что Modulea определяет две функции: func1() и func2() и один класс: Class1 from Modulea import func1func1 () func2 () # это приведет к ошибке, так как имя не определено, как и полное имя Modulea.func2() a = Class1 () # это приведет к ошибке, так как имя не определено, как и полное имя Modulea.Class1()
Поскольку это напрямую импортирует имена (без уточнения), существующие имена могут быть перезаписаны без предупреждений.
Специальная форма оператора from ... import *
импортирует все имена, определенные в именованном пакете, непосредственно в пространство имен вызывающего модуля. Использование этой формы импорта, хотя и поддерживается в языке, как правило, не рекомендуется, поскольку она загрязняет пространство имен вызывающего модуля и приведет к перезаписи уже определенных имен в случае конфликтов имен. [14]
Python также поддерживает import x as y
способ предоставления псевдонима или альтернативного имени для использования вызывающим модулем:
импортировать numpy как npа = нп . диапазон ( 1000 )
В XML спецификация пространства имен XML позволяет именам элементов и атрибутов в документе XML быть уникальными, аналогично роли пространств имен в языках программирования. Используя пространства имен XML, документы XML могут содержать имена элементов или атрибутов из более чем одного словаря XML.
Пространства имен были введены в PHP с версии 5.3 и далее. Можно избежать конфликта имен классов, функций и переменных. В PHP пространство имен определяется с помощью блока пространства имен.
# Файл phpstar/foobar.phpпространство имен phpstar ;class FooBar { public function foo () : void { echo 'Привет, мир, из функции foo' ; } public function bar () : void { echo 'Привет, мир, из функции bar' ; } }
Мы можем ссылаться на пространство имен PHP следующими способами:
# Файл index.php# Включить файл include "phpstar/foobar.php" ;# Вариант 1: непосредственно префикс имени класса с пространством имен $obj_foobar = new \phpstar\FooBar ();# Вариант 2: импорт пространства имен use phpstar\FooBar ; $obj_foobar = new FooBar ();# Вариант 2a: импорт и создание псевдонима для пространства имен use phpstar\FooBar as FB ; $obj_foobar = new FB ();# Доступ к свойствам и методам обычным способом $obj_foobar -> foo (); $obj_foobar -> bar ();
В языках программирования, не имеющих языковой поддержки пространств имен, пространства имен могут быть эмулированы в некоторой степени с помощью соглашения об именовании идентификаторов . Например, библиотеки C , такие как libpng, часто используют фиксированный префикс для всех функций и переменных, которые являются частью их открытого интерфейса. Libpng предоставляет идентификаторы, такие как:
png_create_write_structpng_get_signaturepng_read_rowpng_set_invalid
Такое соглашение об именовании обеспечивает разумную гарантию того, что идентификаторы являются уникальными и, следовательно, могут использоваться в более крупных программах без конфликтов имен . [15] Аналогично, многие пакеты, изначально написанные на Фортране (например, BLAS , LAPACK ), резервируют первые несколько букв имени функции, чтобы указать, к какой группе она принадлежит.
У этой методики есть несколько недостатков:
DGEMM
указывает, что она работает с числами двойной точности («D») и общими матрицами («GE»), и только последние два символа показывают, что она на самом деле делает: умножение матрицы на матрицу («MM»).Есть несколько преимуществ:
Первичная конструкция, устанавливаемая файловой системой, — это иерархическое пространство имен каталогов, которое является логическим репозиторием для файлов.
Пространство имен — это не что иное, как группа сборок, классов или типов. Пространство имен действует как контейнер — как папка на диске — для классов, организованных в группы, как правило, на основе функциональности.
Синтаксис
пространства имен C# позволяет вкладывать пространства имен.
Что такое пространства имен? В самом широком определении пространства имен — это способ инкапсуляции элементов. Во многих местах это можно рассматривать как абстрактную концепцию. Например, в любой операционной системе каталоги служат для группировки связанных файлов и действуют как пространство имен для файлов внутри них.
Пакет — это группа связанных типов, обеспечивающая защиту доступа и управление пространством имен. Обратите внимание, что типы относятся к
классам
,
интерфейсам
,
перечислениям
и типам аннотаций. Перечисления и типы аннотаций — это особые виды классов и интерфейсов соответственно, поэтому в этом уроке типы часто называются просто классами и интерфейсами.[ нужен лучший источник ]
Например, [в
Windows
], чтобы получить доступ к встроенным классам ввода-вывода (I/O) и членам, используйте пространство имен System.IO. Или, чтобы получить доступ к классам и членам, связанным с Web, используйте пространство имен System.Web.
{{cite web}}
: CS1 maint: bot: original URL status unknown (link)