В вычислительной технике пространство имен — это набор знаков ( имен ), которые используются для идентификации и обращения к объектам различных видов. Пространство имен гарантирует, что все объекты данного набора имеют уникальные имена, чтобы их можно было легко идентифицировать .
Пространства имен обычно структурируются в виде иерархий, что позволяет повторно использовать имена в разных контекстах. В качестве аналогии рассмотрим систему именования людей , в которой у каждого человека есть имя, а также фамилия, общая с его родственниками. Если имена членов семьи уникальны только внутри каждой семьи, то каждого человека можно однозначно идентифицировать по сочетанию имени и фамилии; есть только одна Джейн Доу, хотя Джейн может быть много. В пространстве имен семьи Доу достаточно просто «Джейн», чтобы однозначно обозначить этого человека, тогда как в «глобальном» пространстве имен всех людей необходимо использовать полное имя.
Яркими примерами пространств имен являются файловые системы , которые присваивают имена файлам. [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] Имя пространства имен обычно применяется как префикс к локальному имени.
В дополненной форме Бэкуса – Наура :
name = < имя пространства имен > разделитель < локальное имя >
Когда локальные имена используются сами по себе, разрешение имен используется для определения того, какое конкретное имя (если таковое имеется) ссылается на какое-то конкретное локальное имя.
Делегирование ответственности между сторонами важно в реальных приложениях, таких как структура Всемирной паутины. Пространства имен позволяют делегировать присвоение идентификатора нескольким организациям, выдающим имена, сохраняя при этом глобальную уникальность. [8] Центральный орган регистрации регистрирует назначенные имена пространств имен . Каждое имя пространства имен выделяется организации, которая впоследствии несет ответственность за присвоение имен в выделенном им пространстве имен. Эта организация может быть организацией, выдающей имена, которая сама присваивает имена , или другим органом регистрации , который в дальнейшем делегирует части своего пространства имен различным организациям.
Схема именования, которая позволяет делегировать пространства имен третьим сторонам, представляет собой иерархическое пространство имен .
Иерархия является рекурсивной, если синтаксис имен пространств имен одинаков для каждого подделегирования. Примером рекурсивной иерархии является система доменных имен .
Примером нерекурсивной иерархии является единое имя ресурса , представляющее номер Управления присвоения номеров Интернета (IANA).
Имя пространства имен может обеспечивать контекст ( область действия в информатике) для имени, и эти термины иногда используются как взаимозаменяемые. Однако контекст имени также может зависеть от других факторов, таких как место, где оно встречается, или синтаксис имени.
Для многих языков программирования пространство имен является контекстом для их идентификаторов . В операционной системе примером пространства имен является каталог. Каждое имя в каталоге однозначно идентифицирует один файл или подкаталог. [9]
Как правило, имена в пространстве имен не могут иметь более одного значения; то есть разные значения не могут использовать одно и то же имя в одном пространстве имен. Пространство имен также называется контекстом , поскольку одно и то же имя в разных пространствах имен может иметь разные значения, каждое из которых соответствует своему пространству имен.
Ниже приведены другие характеристики пространств имен:
Помимо технического использования абстрактного языка, как описано выше, в некоторых языках есть определенное ключевое слово, используемое, помимо прочего, для явного управления пространством имен. Ниже приведен пример пространства имен в C++:
#include <iostream> // Вот как можно перенести имя в текущую область видимости. В данном случае это // перенос их в глобальную область видимости. используя std :: cout ; используя 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 ) идентификаторы, именующие пространства имен, сами связаны с включающим пространством имен. Таким образом, в этих языках пространства имен могут вкладываться, образуя дерево пространств имен . В корне этого дерева находится безымянное глобальное пространство имен .
В C можно использовать анонимные структуры в качестве пространств имен, начиная с C99 .
// helper.c static int _add ( int a , int b ) { return a + b ; } const struct { двойное пи ; интервал ( * добавить ) ( интервал , интервал ); } Помощник = { 3.14 , _add }; // helper.h const struct { double pi ; интервал ( * добавить ) ( интервал , интервал ); } помощник ; // main.c #include <stdio.h> #include "helper.h" int main ( ){ printf ( "3 + 2 = %d \n " , helper.add ( 3 , 2 ) ); printf ( "pi is %f \ n " , helper.pi ) ; }
В C++ пространство имен определяется блоком пространства имен. [11]
пространство имен abc { int bar ; }
Внутри этого блока идентификаторы могут использоваться точно так, как они объявлены. За пределами этого блока спецификатор пространства имен должен иметь префикс. Например, вне namespace abc
, для доступа bar
необходимо написать . abc::bar
В C++ есть еще одна конструкция, которая делает это многословие ненужным. Добавив строку
используя пространство имен abc ;
к фрагменту кода префикс abc::
больше не нужен.
Идентификаторы, которые не объявлены явно в пространстве имен, считаются находящимися в глобальном пространстве имен.
интервал фу ;
Эти идентификаторы можно использовать точно так, как они объявлены, или, поскольку глобальное пространство имен не имеет имени, спецификатор пространства имен ::
может иметь префикс. Например, 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
in может называться (это известно как полное имя класса ). Как и 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 организованы в пространства имен, чтобы их можно было использовать более четко и избежать хаоса. Более того, пользовательские пространства имен широко используются программистами как для организации своей работы, так и для предотвращения конфликтов имен . При ссылке на класс следует указать либо его полное имя, что означает пространство имен, за которым следует имя класса,
Система . Консоль . WriteLine ( "Привет, мир!" ); int я = Система . Конвертировать . ToInt32 ( «123» );
или добавьте оператор использования . Это устраняет необходимость указывать полное имя всех классов в этом пространстве имен.
используя систему ; Консоль . WriteLine ( "Привет, мир!" ); int я = Конвертировать . ToInt32 ( «123» );
В приведенных выше примерах System — это пространство имен, а Console и Convert — это классы, определенные в System .
В Python пространства имен определяются отдельными модулями, а поскольку модули могут содержаться в иерархических пакетах, пространства имен также являются иерархическими. [12] [13] Обычно, когда модуль импортируется, имена, определенные в модуле, определяются через пространство имен этого модуля и доступны из вызывающих модулей с использованием полного имени.
# предположим, что Modulea определяет две функции: func1() и func2() и один класс: Class1 import ModuleaМодульа . func1 () Модульa . func2 () a = Modulea . Класс1 ()
Этот from ... import ...
оператор можно использовать для вставки соответствующих имен непосредственно в пространство имен вызывающего модуля, и к этим именам можно получить доступ из вызывающего модуля без уточненного имени:
# предположим, что Modulea определяет две функции: func1() и func2() и один класс: Class1 из 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 ;класс FooBar { public function foo () : void { echo 'Привет, мир, из функции foo' ; } public function bar () : void { echo 'Привет, мир, из функциональной панели' ; } }
Мы можем ссылаться на пространство имен PHP следующими способами:
# Файл index.php# Подключаем файл include "phpstar/foobar.php" ;# Вариант 1: непосредственно добавить к имени класса префикс пространства имен $obj_foobar = new \phpstar\FooBar ();# Вариант 2: импортировать пространство имен , используя phpstar\FooBar ; $obj_foobar = новый FooBar ();# Вариант 2a: импортировать и создать псевдоним пространства имен, использовать phpstar\FooBar как FB ; $obj_foobar = новый ФБ ();# Доступ к свойствам и методам обычным способом $obj_foobar -> foo (); $obj_foobar -> бар ();
В языках программирования, в которых отсутствует языковая поддержка пространств имен, пространства имен можно в некоторой степени эмулировать с помощью соглашения об именовании идентификаторов . Например, библиотеки C , такие как libpng, часто используют фиксированный префикс для всех функций и переменных, которые являются частью их открытого интерфейса. Libpng предоставляет такие идентификаторы, как:
png_create_write_structpng_get_signaturepng_read_rowpng_set_invalid
Это соглашение об именах обеспечивает разумную гарантию того, что идентификаторы уникальны и, следовательно, могут использоваться в более крупных программах без конфликтов имен . [15] Аналогично, многие пакеты, изначально написанные на Фортране (например, BLAS , LAPACK ), резервируют первые несколько букв имени функции, чтобы указать, к какой группе она принадлежит.
Эта технология имеет ряд недостатков:
DGEMM
указывает на то, что она работает с числами двойной точности («D») и общими матрицами («GE»), и только два последних символа показывают, что она на самом деле делает: умножение матрицы на матрицу ( «ММ»).Есть несколько преимуществ:
Основная конструкция, установленная файловой системой, — это иерархическое пространство имен каталогов, которое является логическим хранилищем файлов.
Пространство имен — это не что иное, как группа сборок, классов или типов.
Пространство имен действует как контейнер (например, папка на диске) для классов, организованных в группы, обычно в зависимости от функциональности.
Синтаксис
пространств имен C#
позволяет вкладывать пространства имен.
Что такое пространства имен?
В самом широком определении пространства имен — это способ инкапсуляции элементов.
Во многих местах это можно рассматривать как абстрактную концепцию.
Например, в любой операционной системе каталоги служат для группировки связанных файлов и служат пространством имен для файлов внутри них.
Пакет — это группа связанных типов, обеспечивающая защиту доступа и управление пространством имен.
Обратите внимание, что типы относятся к
классам
,
интерфейсам
,
перечислениям
и типам аннотаций.
Типы перечислений и аннотаций представляют собой особые виды классов и интерфейсов соответственно, поэтому в этом уроке типы часто называются просто классами и интерфейсами.[ нужен лучший источник ]
Например, [в
Windows
] для доступа к встроенным классам и членам ввода-вывода (I/O) используйте пространство имен System.IO.
Или для доступа к классам и членам, связанным с Интернетом, используйте пространство имен System.Web.
{{cite web}}
: CS1 maint: bot: original URL status unknown (link)