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

Материал из Deeptown Manual

Перейти к: навигация, поиск

Как уже было сказано в предыдущем разделе, для организации кода применяются пакеты. Каждый пакет представляет собой контейнер, содержащий в себе сущности вроде классов, функций и глобальных переменных. При этом, в разных пакетах могут содержаться одноименные сущности, например классы. Более того, пользователь этих пакетов может импортировать оба пакета и использовать оба этих класса независимо. Достигается это введением концепции пространств имен. При этом, имена всех сущностей предворяются именем контейнера в котором они расположены. Таким образом, полное имя двух одноименных классов, расположенных в разных пакетах, все равно будет различным и конфликта имен не происходит.

Например, в стандартной библиотеке существует класс Node, представляющий элемент файловой системы DISS. Одновременно с ним, в пакете World существует класс Node, представляющий уже элемент иерархии графических объектов.

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

  1. package MyPackage;
  2.  
  3. //import std; //(стандартная библиотека импортируется автоматически)
  4. import World; //подключаем пакет управления миром
  5.  
  6. var   std::Node node1 = std::Storage.open('test.txt', std::Node.MODE_READ);
  7. var World::Node node2 = World::Graphics.sceneManager.root.createChildNode('MyNode');

В этом примере создаются две переменные, node1 и node2, инициализируемые инстанциями классов std::Node и World::Node соответственно. Везде где используются классы из импортируемых пакетов, применяются полные пути к классам. Однако, на практике писать префиксы неудобно. Для облегчения работы программиста, предусмотрена специальная конструкция для автоматической подстановки пространств имен. Для ее использования, необходимо указать ключевое слово using, следом за которым записать полный путь к необходимому пространству имен.

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

Перепишем предыдущий пример с использованием конструкции using:

  1. package MyPackage;
  2.  
  3. //import std; // (стандартная библиотека импортируется и используется автоматически)
  4. //using std;  // (стандартная библиотека используется автоматически)
  5.  
  6. import World; // подключаем пакет управления миром
  7. using World;  // используем его по умолчанию
  8.  
  9. var node1 = Storage.open('test.txt', Node.MODE_READ);
  10. var node2 = Graphics.sceneManager.root.createChildNode('MyNode');

Примечание: Применять оператор using можно не только ко всему пакету, но и к некоторой его части. Если using указывается внутри тела функции или одного из ее блоков, то подстановка префиксов будет осуществляться в тех же границах что и область видимости данного блока. Такой подход более удобен, поскольку импортируемый пакет используется только в тех местах где это действительно необходимо, притом что в остальных местах импортируемые классы будут "не видны".

документация