Пакеты и импорт
Каждый файл может содержать классы (classes), перечисления (enums) и операторы импорта (imports). Все они являются частью пакета (package) и объявляются в начале класса. Если пакет не указан, то по-умолчанию будет использован пустой пакет. Каждый тип (type) имеет путь (path), который состоит из имени пакета, в котором находится тип и, собственно, имени этого типа.
// file my/pack/C.hx package my.pack; enum E { } class C { }
В примере выше объявлены два типа : my.pack.E и my.pack.C. Можно объявлять несколько классов в одном и том же файле, но их имена (с названием пакета) должны быть уникальны в пределах приложения, поэтому при неправильном использовании пакетов могут возникнуть конфликты (что, тем не менее, не обязывает вас использовать длинные названия пакетов везде).
При использовании пакетов файлы должны быть помещены в подпапки, имена которых должны совпадать с именами пакетов. Называть файл принято так же как и основной класс, который в нем определён.
Расширение Haxe файлов — .hx.
Название пакета должно начинаться с маленькой буквы, а название типа (и соответственно название файла, прим. пер.) должно начинаться с большой. Таким образом, название пакета My.Pack не корректно, также как и my.Pack. Некорректным, так же, будет и название типа my.pack.e.
Операторы импорта (Imports)
Операторы импорта могут использоваться для доступа ко всем типам в файле без явного указания имени пакета.
Запись:
package my.pack2; class C2 extends my.pack.C { }
эквивалентна:
package my.pack2; import my.pack.C; class C2 extends C { }
Разница лишь в том, что при использовании оператора импорта у вас появляется возможность использовать еще и перечисление, которое было объявлено в файле my/pack/C.hx (см. выше).
Автоматическое добавление статических методов в экземпляры классов
Когда ключевое слово using импортирует файл, все статические методы из этого файла становятся заодно методами, которые можно применить к типу их первого аргумента.
Например:
package my.pack; class StringUtils { public static function double( string:String ):String { return string + string; } }
Так мы импортируем этот класс и удваиваем строку:
import my.pack.StringUtils; StringUtils.double( "Hello!"); // returns "Hello!Hello!"
На самом деле, мы можем после импорта использовать следующий синтаксис:
using my.pack.StringUtils; "Hello!".double(); // returns "Hello!Hello!"
Импорт единственного типа из модуля
Пусть у на есть модуль с несколькими типами, вроде
package my.pack2; typedef A = { a : String } typedef B = { b : String }возможно импортировать только один тип из этого модуля:
import my.pack2.A;
Импорт по маске ('*')
Импорт по маске НЕ поддерживается в Haxe, то есть
import flash.display.*;
выдаст сообщение об ошибке компилятора: x.hx:1: characters x-x : Unexpected *
Вывод типов
Когда обнаружено имя типа, его определение ищется в следующем порядке:
- параметризующие типы текущего класса
- стандартные типы
- типы, объявленные в текущем файле
- типы, объявленные в импортируемых файлах (если в данном пакете объявление не найдено)
- если определение все еще не обнаружено, загружается соответствующий файл и тип ищется внутри него
Конструкторы перечисления
Для того, чтобы использовать конструкторы перечисления нужно импортировать файл в котором определено это перечисление, или же, можно использовать полный путь к конструкторам так, как если бы они были статическим полями перечисления.
var c : my.pack.Color = my.pack.Color.red;
Из этого правила есть исключение. В операторе switch, если тип перечисления известен во время компиляции, можно использовать конструкторы напрямую, без необходимости импорта.