Пространства имен
Как уже было сказано в предыдущем разделе, для организации кода применяются пакеты. Каждый пакет представляет собой контейнер, содержащий в себе сущности вроде классов, функций и глобальных переменных. При этом, в разных пакетах могут содержаться одноименные сущности, например классы. Более того, пользователь этих пакетов может импортировать оба пакета и использовать оба этих класса независимо. Достигается это введением концепции пространств имен. При этом, имена всех сущностей предворяются именем контейнера в котором они расположены. Таким образом, полное имя двух одноименных классов, расположенных в разных пакетах, все равно будет различным и конфликта имен не происходит.
Например, в стандартной библиотеке существует класс Node, представляющий элемент файловой системы DISS. Одновременно с ним, в пакете World существует класс Node, представляющий уже элемент иерархии графических объектов.
При объявлении инстанций таких классов, помимо самого имени класса необходимо указывать и имя пакета, отделяемое с помощью символа двойное двоеточие (::): <source lang="kpp" line="1"> package MyPackage;
//import std; //(стандартная библиотека импортируется автоматически) import World; //подключаем пакет управления миром
var std::Node node1 = std::Storage.open('test.txt', std::Node.MODE_READ); var World::Node node2 = World::Graphics.sceneManager.root.createChildNode('MyNode'); </source>
В этом примере создаются две переменные, node1 и node2, инициализируемые инстанциями классов std::Node и World::Node соответственно. Везде где используются классы из импортируемых пакетов, применяются полные пути к классам. Однако, на практике писать префиксы неудобно. Для облегчения работы программиста, предусмотрена специальная конструкция для автоматической подстановки пространств имен. Для ее использования, необходимо указать ключевое слово using, следом за которым записать полный путь к необходимому пространству имен.
После этого, имена классов можно указывать без префиксов. Поиск по пакетам будет осуществляться последовательно, в соответствии с очередностью их импортирования. Считается, что стандартная библиотека импортируется и используется по умолчанию. Поэтому, имена базовых классов, таких как int всегда записывались без префиксов.
Перепишем предыдущий пример с использованием конструкции using: <source lang="kpp" line="1"> package MyPackage;
//import std; // (стандартная библиотека импортируется и используется автоматически) //using std; // (стандартная библиотека используется автоматически)
import World; // подключаем пакет управления миром using World; // используем его по умолчанию
var node1 = Storage.open('test.txt', Node.MODE_READ); var node2 = Graphics.sceneManager.root.createChildNode('MyNode'); </source>
Примечание: Применять оператор using можно не только ко всему пакету, но и к некоторой его части. Если using указывается внутри тела функции или одного из ее блоков, то подстановка префиксов будет осуществляться в тех же границах что и область видимости данного блока. Такой подход более удобен, поскольку импортируемый пакет используется только в тех местах где это действительно необходимо, притом что в остальных местах импортируемые классы будут "не видны".