Компания Google опубликовала релиз языка программирования Dart 2.15, продолживший развитие кардинально переработанной ветки Dart 2, которая отличается от изначального варианта языка Dart применением сильной статической типизации (типы могут выводиться автоматически, поэтому указание типов не является обязательным, но динамическая типизация больше не используется и вычисленный изначально тип закрепляется за переменной и в дальнейшем применяется строгая проверка типа).
Особенности языка Dart:
- Привычный и простой для изучения синтаксис, естественный для программистов на JavaScript, Си и Java.
- Обеспечение быстрого запуска и высокой производительности для всех современных web-браузеров и различных типов окружений, от портативных устройств до мощных серверов.
- Возможность определения классов и интерфейсов, позволяющих использовать инкапсуляцию и повторно использовать существующие методы и данные.
- Указание типов позволяет упростить отладку и выявление ошибок, делает код более ясным и читаемым, упрощает его доработку и анализ сторонними разработчиками.
- Среди поддерживаемых типов: различные виды хэшей, массивов и списков, очереди, числовые и строковые типы, типы для определения даты и времени, регулярные выражения (RegExp). Имеется возможность создания своих типов.
- Для организации параллельного выполнения предлагается использовать классы с атрибутом isolate, код которых выполняется полностью в изолированном пространстве в отдельной области памяти, взаимодействуя с основным процессом через отправку сообщений.
- Поддержка использования библиотек, упрощающих поддержку и отладку больших web-проектов. Сторонние реализации функций могут подключаться в виде разделяемых библиотек. Приложения можно разбить на части и поручить разработку каждой из частей отдельной команде программистов.
- Набор готовых инструментов для поддержки разработки на языке Dart, включая реализацию средств динамической разработки и отладки с исправлением кода на лету (“edit-and-continue”).
- Для упрощения разработки на языке Dart поставляется SDK, пакетный менеджер pub, статический анализатор кода dart_analyzer, набор библиотек, интегрированная среда разработки DartPad и плагины с поддержкой Dart для IntelliJ IDEA, WebStorm, Emacs, Sublime Text 2 и Vim.
- Дополнительные пакеты с библиотеками и утилитами распространяются через репозиторий pub, который насчитывает около 22 тысяч пакетов.
Основные изменения в выпуске Dart 2.15:
- Предоставлены средства для быстрого параллельного выполнения задач с изоляцией обработчиков. На многоядерных системах Dart runtime по умолчанию выполняет код приложения на одном ядре CPU, а другие ядра привлекает для выполнения системных задач, таких как асинхронный ввод/вывод, запись в файлы или совершение сетевых вызовов. Для приложений, которым необходимо параллельно выполнять свои обработчики, например, для отрисовки анимации в интерфейсе, предусмотрена возможность запуска отдельных блоков кода (isolate), изолированных друг от друга и выполняемых на других ядрах CPU одновременно с основным потоком приложения. Для защиты от ошибок, возникающих при одновременном выполнении кода, работающего с одним набором данных, запрещено совместное использование изменяемых объектов в разных в isolate-блоках, а для взаимодействия между обработчиками применяется модель на основе передачи сообщений.
В Dart 2.15 предложена новая концепция – группы изолированных блоков (isolate groups), позволяющая организовать совместный доступ к различным внутренним структурам данных в isolate-блоках, входящих в одну группу, что позволяет значительного снизить накладные расходы при взаимодействии обработчиков в группе. Например, запуск дополнительного
isolate-блока в существующей группе выполняется в 100 раз быстрее и требует в 10-100 раз меньше памяти, чем запуск обособленного isolate-блока, за счёт исключения необходимости инициализации структур данных программы.Несмотря на то, что в isolate-блоках в группе по-прежнему запрещён совместный доступ к изменяемым объектам, в группах используется общая heap-память, что позволяет значительно ускорить передачу объектов из одного блока в другой без необходимости выполнения ресурсоёмких операций копирования. В новой версии также разрешено передавать результат работы обработчика при вызове Isolate.exit() для передачи в родительский isolate-блок без операций копирования. Кроме того проведена оптимизация механизма передачи сообщений – небольшие и средние сообщения теперь обрабатываются приблизительно в 8 раз быстрее. В число объектов, которые можно передавать между isolate-блоками при помощи вызова SendPort.send(), включены некоторые типы функций, замыкания и трассировки стека.
- В средствах для создания указателей на отдельные функции в других объектах (tear-off) сняты ограничения по созданию подобных указателей в коде конструкторов, что может быть полезным при построении интерфейсов на базе библиотеки Flutter. Например, для создания виджета
Column, включающего несколько виджетов Text, можно вызвать “.map()” и передать указатели в конструктор Text.new объекта Text: class FruitWidget extends StatelessWidget { @override Widget build(BuildContext context) { return Column( children: [‘Apple’, ‘Orange’].map(Text.new).toList()); } } - Расширены возможности, связанные с использованием указателей на функции. Добавлена возможность применять обобщённые (generic) методы и указатели функций для создания не-generic метода и указателя: T id(T value) => value; var intId = id; // разрешено в версии 2.15 вместо “int Function(int) intId = id;” const fo = id; // указатель на фунецию id. const c1 = fo;
- В библиотеке dart:core улучшена поддержка перечислений (enum), например, теперь можно выводить строковое значение из каждого значения enum при помощи метода “.name”, осуществлять выборку значений по имени или выполнять сопоставление пар значений: enum MyEnum { one, two, three } void main() { print(MyEnum.one.name); // будет выведено “one”. print(MyEnum.values.byName(‘two’) == MyEnum.two); // будет выведено “true”. final map = MyEnum.values.asNameMap(); print(map[‘three’] == MyEnum.three); // “true”. }
- Реализована техника сжатия указателей, позволяющая использовать в 64-разрядном SDK более компактное представление указателей, если для адресации достаточно 32-разрядного адресного пространства (используется не более 4 ГБ памяти). Тесты показали, что подобная оптимизация даёт возможность сократить размер кучи приблизительно на 10%. Во Flutter SDK по умолчанию новый режим уже активирован для Android, а в будущем выпуске запланирован для включения для iOS.
- В состав Dart SDK включены инструменты для отладки и анализа производительности (DevTools), которые раньше поставлялись в отдельном пакете.
- В команду “dart pub” и репозитории пакетов pub.dev добавлены средства для отслеживания случайной публикации конфиденциальной информации, например, оставление внутри пакета учётных данных для систем непрерывной интеграции и облачных окружений. В случае выявление подобных утечек выполнение команды “dart pub publish” будет прервана с сообщением об ошибке. В случае если имело место ложное срабатывание предоставлена возможность обхода проверки через белый список.
- В репозиторий pub.dev добавлена возможность отзыва уже опубликованной версии пакета, например, в случае выявления опасных ошибок или уязвимостей. Ранее для подобных исправлений практиковалась публикация следом корректирующей версии, но в некоторых ситуациях требуется именно отменить состоявшийся выпуск (например, если исправления ещё не готово или если по ошибке вместо тестовой версии был опубликован полноценный выпуск). После отзыва пакет перестаёт определяться в командах “pub get” и “pub upgrade”, а на уже установивших его системах при очередном выполнении “pub get” выдаётся специальное предупреждение.
- Добавлена защита от уязвимости (CVE-2021-22567), вызванных применением в коде unicode-символов, меняющих порядок отображения.
- Устранена уязвимость (CVE-2021-22568), позволяющая выдать себя за другого пользователя pub.dev при публикации пакетов на сторонний сервер, принимающий oauth2-токены доступа pub.dev. Например, уязвимость может применяться для атаки на внутренние и корпоративные серверы пакетов.
Разработчиков, размещающих пакеты только на pub.dev, проблема не затрагивает.
Одновременно представлен значительный релиз фреймворка построения интерфейса пользователя Flutter 2.8, который рассматривается как альтернатива React Native и позволяет на основе одной кодовой базы выпускать приложения для платформ iOS, Android, Windows, macOS и Linux, а также создавать приложения для запуска в браузерах. На основе Flutter построена пользовательская оболочка развиваемой в Google микроядерной операционной системы Fuchsia. Отмечается, что за последние шесть месяцев число приложений на Flutter 2 в Google Play Store увеличилось с 200 тысяч до 375 тысяч, т.е. почти в два раза.
Основная часть кода Flutter реализована на языке Dart, а runtime-движок для выполнения приложений написан на C++. При разработке приложений, помимо родного для Flutter языка Dart, можно использовать интерфейс Dart Foreign Function для вызова кода на C/C++. Высокая производительность выполнения достигается благодаря компиляции приложений в машинный код для целевых платформ. При этом программу не нужно перекомпилировать после каждого изменения – Dart предоставляет режим горячей перезагрузки, позволяющий вносить изменения в работающее приложение и сразу оценивать результат.
Из изменений в новом выпуске Flutter отмечается проведение оптимизации скорости запуска и потребления памяти на мобильных устройствах. Упрощено подключение приложений к бэкенд-сервисам, таким как Firebase и Google Cloud. Стабилизированы инструменты для интеграции с Google Ads. Значительно улучшена поддержка камер и web-плагинов. Предложены новые средства для упрощения разработки, например, добавлен виджет для аутентификации с использованием Firebase
Обновлён движок Flame, предназначенный на разработки 2D-игр с использованием Flutter.