Новые возможности Haxe 3

Абстрактные типы

  • Объяснение: Абстрактный тип - это нечто, реально не существующее во время выполнения программы, и представлено другим, неабстрактным типом. Haxe 3 предоставляет возможности четкого семантического определения абстрактного типа, включая неявное преобразование, перегрузку операторов и определение собственного синтаксиса доступа к элементу массива.
  • Пример:
  • Больше информации: Abstract Types

Выражения массивов

  • Объяснение: Синтаксис выражения массива haxe 3 направлен на предоставление выразительного способа инициализации массивов, при этом сохраняя читабельность, что часто упускается в других языках. Синтаксис построен вокруг уже известных выражений for, while и if внутри объявления массива ''[ ]'.
  • Пример:
    // четные числа от 0 до 20
    var a = [for (i in 0...21) if (i & 1 == 0) i];
    trace(a); // [0,2,4,6,8,10,12,14,16,18,20]
    
    // части пути файла (используя haxe.io.Path)
    var path = "/top/bar/foo/File.hx";
    var pathParts = [while ((path = haxe.io.Path.directory(path)) != "") path];
    trace(pathParts); // [/top/bar/foo,/top/bar,/top]

Обобщенные (generic) функции

  • Объяснение: Haxe 3 позволяет задать мета-данные @:generic для конкретной функции, и это будет работать точно так же как эквивалент для классов: Функция будет специфицирована для каждой комбинации параметров типа, что может дать прирост производительности на статических платформах. В качестве бонуса, параметры типа могут быть сконструированы, если задано ограничение, требующее наличие функции new.
  • Пример:
        @:generic static function foo<T:{function new(s:String):Void;}>(t:T) {
            trace(Type.typeof(t)); // TClass([class String]) / TClass([class Template])
            return new T("foo");
        }
        
        static public function test() {
            var s = foo("foo");
            var t = foo(new haxe.Template("bar"));
            trace(s); // foo
            trace(t); // haxe.Template
        }

Словари (Map)

  • Объяснение: Haxe 2 предоставлял “словарные” структуры данных для строковых и целочисленных ключей. С haxe 3 появилась возможность использовать почти любые объекты в качестве ключей, используя единый класс верхнего уровня:Map. Сгенерированный код автоматически использует наиболее оптимальную структуру данных для указанного типа ключа.
  • Пример:
    // Строковые ключи с целочисленными значениями
    var map = new Map();
    map.set("foo", 99);
    trace(map.get("foo")); // 99
    
    // Целочисленные ключи с целочисленными значениями
    var map = new Map();
    map.set(6, 7);
    trace(map.get(6)); // 7
    
    // Ключи-объекты со значениями-функциями
    var http = new haxe.Http("haxe.org");
    var map = new Map();
    map.set(http, function() return "haxe.org");
    trace(map.get(http)()); // haxe.org

В качестве бонуса, словари предоставляют синтаксис аналогичный синтаксису доступа к элементу массива:

var map = new Map();
map["foo"] = 9;
trace(map["foo"]); // 9
map["foo"] += 12;
trace(map["foo"]); // 21

Кроме того, теперь можно использовать оператор "=>', как описано здесь:
Jason объясняет новую возможность =>

Реификация (reification) макросов

  • Объяснение: Хотя реификация макросов и была в haxe 2, она была неполноценна во многих областях и требовала дополнительной ручной работы. Эта ситуация была сильно улучшена в haxe 3, и теперь реификация макросов очень похожа на интерполяцию строк.
  • Пример:
    var e1 = macro 4; // Обычная константа 4
    var e2 = macro $e1 + 2; // Бинарный оператор 4 + 2;
    // дальше начинается haxe 3 only 
    var e3 = macro myFunc($a{[$e1, $e2]}); // вызов myFunc использующий 4 и 4 + 2 в качестве аргументов
    var e4 = macro $p{["haxe", "Log", "trace"]}; // путь к haxe.Log.trace
    var ident = "varName";
    var e5 = macro trace($i{ident}); // вызов trace с идентификатором varName в качестве аргумента
    var e6 = macro $b{[e1,e2,e3,e4,e5]}; // блок со всем вышеперечисленным кодом

Сопоставление с образцом

  • Объяснение: Хотя перечисления (enum) уже были мощной алгебраической структурой (ADT) на протяжении всего времени существования haxe, было довольно многословно работать с ними с использованием switch, в случае, когда нужно получить информацию с глубокого уровня вложенности. Сопоставление по образцу Haxe 3 (pattern matching) призвано спасти положение, позволяя не только проверять вложенные перечисления, но также структуры и массивы.
  • Пример:
    var expr = macro someCall("1");
    switch(expr.expr) {
        case ECall({expr: EConst(CIdent("someCall")) }, [{expr: EConst(arg)}]):
            trace("Some call to: " +arg); // Some call to: CString(1)
        case _:
            trace ("No match");
    }
  • Больше информации: Pattern Matching
version #19509, modified 2013-06-20 17:52:00 by nadako