[Программирование, Разработка мобильных приложений, Dart, Flutter] Dart 2.12: Sound null safety и Dart FFI отправлены на стабильный канал (перевод)

Автор Сообщение
news_bot ®

Стаж: 6 лет 9 месяцев
Сообщений: 27286

Создавать темы news_bot ® написал(а)
23-Мар-2021 17:32

Представляем вам перевод статьи, анонсирующей выход Dart 2.12. Да, знаем, что сильно опоздали с публикацией: оригинал вышел 3 марта. Тем не менее, Dart 2.12 — важный релиз, и мы решили опубликовать материал.Вышел Dart 2.12. В нём — стабильные версии sound null safety и Dart FFI. Null safety – наша самая свежая масштабная фича. Её цель – повысить производительность: помочь вам избежать null error. Проблемы, вызванные этой ошибкой, зачастую тяжело заметить в коде. Об этом мы подробно рассказали во вводном видео. FFI – это механизм взаимодействия, позволяющий вызывать уже имеющийся код на языке C. Например, обращаться к Windows Win32 API. Доступ к Dart 2.12 уже открыт.
Уникальные функциональные возможности платформы, на которой работает DartПрежде чем подробнее поговорить о sound null safety и FFI, предлагаю обсудить, как они связаны с нашими планами развития платформы под Dart. Как правило у языков программирования много похожих возможностей. К примеру, многие языки поддерживают объектно ориентированное программирование или работу в web. Настоящие различия между языками заключаются в их уникальных комбинациях функциональных возможностей.
Уникальная комбинация функциональных возможностей для создания приложенийПереносимостьНативная производительность: Компиляция в машинный код или оптимизированный JSРазвитые, консистентные мультиплатформенные библиотекиПродуктивностьБыстрый hot reload для поэтапной разработкиМногопоточность и изолятыНадёжностьНадёжная null-safe система с динамической идентификацией типовМасштабируемость и надёжность уровня GoogleУникальные функциональные возможности Dart можно распределить по трём направлениям:
  • Переносимость. Продуктивные компиляторы генерируют машинный код x86 и ARM для устройств и оптимизированный JavaScript код для web. Dart поддерживает целый ряд целевых платформ: мобильные приложения, ПК, серверную часть приложений и многое другое. Богатый выбор библиотек и пакетов обеспечивает консистентность API, работающих на всех платформах: создавать мультиплатформенные приложения становится ещё дешевле.
  • Продуктивность. Платформа для Dart поддерживает hot reload, благодаря чему процесс разработки становится быстрым и итеративным. Кроме того, в Dart есть такие многофункциональные структурные элементы, как изоляты и async/await для работы с распространенными многопоточными и событийно-ориентированными паттернами в приложениях.
  • Надёжность. Надёжная null-safe система типов в Dart находит ошибки прямо в процессе разработки. Платформа в целом очень надёжна, хорошо масштабируется. Более десяти лет она используется в продакшн множеством приложений, включая, к примеру, Google Ads и Google Assistant, бесперебойная работа которых имеет критическое значение для бизнеса.
Sound null safety делает систему типов ещё надежнее и помогает повысить производительность. Благодаря Dart FFI можно использовать уже существующие библиотеки C. Это улучшает переносимость и позволяет интегрировать хорошо отлаженный код на C в задачах, для которых критически важна производительность.Sound null safetySound null safety – самое масштабное дополнение к языку Dart с тех пор, как в Dart 2.0 появилась надежная система типов. Null safety делает систему типов ещё надёжнее. Она позволяет обнаруживать ошибки типа null error ещё в процессе разработки, а значит, вы избежите крашей, когда приложение выйдет в продакшн. Sound null safety базируется на нескольких ключевых принципах. Non-nullable по умолчанию: фундаментальное изменение системы типовДо появления null safety основная проблема была в том, что тяжело заметить разницу между кодом, который ожидает значение null, и кодом, который не обрабатывает null.Несколько месяцев назад мы обнаружили баг в основном канале Flutter. При определённых конфигурациях машины различные команды инструментов Flutter крашились и выдавали null error: The method '>=' was called on null. Причиной стал вот такой код:
final int major = version?.major;
final int minor = version?.minor;
if (globals.platform.isMacOS) {
 // plugin path of Android Studio changed after version 4.1.
 if (major >= 4 && minor >= 1) {
 ...
final int major = version?.major; final int minor = version?.minor; if (globals.platform.isMacOS) {  // plugin path of Android Studio changed after version 4.1.  if (major >= 4 && minor >= 1) {  ...Видите ошибку? Так как у version может быть значение null, оно может быть и у major , и у minor. Когда этот баг вырван из контекста, кажется, что его легко заметить, но на практике такие ошибки всё время остаются незамеченными, даже если код проверяют очень тщательно, как в репозитории Flutter. С приходом null safety такие ошибки тут же всплывают в результатах статического анализа. Попробуйте, как это работает в DartPad.
Скриншот с результатом анализа в IDEИ это довольно простая ошибка. Когда мы ещё только начинали использовать null safety в коде Google, нам встречались куда более запутанные ошибки. О некоторых багах было уже годами известно, но наши команды не могли найти их причину без помощи дополнительных статических проверок от null safety. Вот несколько примеров:
  • В одной команде обнаружили, что часто проверяют на значения null те выражения, в которых в принципе не может быть null. Чаще всего с этой проблемой сталкивались в коде, использующем protobuf, где необязательные поля возвращают значение по умолчанию, если оно не задано, и не могут вернуть null. В результате код неправильно проверял условия по умолчанию: путал значение по умолчанию и значение null.
  • Члены команды Google Pay нашли баги в своём коде во Flutter, когда не смогли получить доступ к объектам Flutter State вне контекста Widget. До null safety такие объекты возвращали null и маскировали ошибку; с null safety глубокий анализ показал, что null не может быть значением в этом случае, и диагностировал ошибку ещё до этапа компиляции.
  • Команда Flutter нашла баг, от которого движок Flutter может крашиться, если параметр scene в Window.render() получает null. Во время миграции на null safety они добавили хинт — mark Scene as non-nullable, благодаря которому легко смогли предотвратить возможные краши приложения, вызванные значением null.
Работа с non-nullable по умолчаниюПосле перехода на null safety основы объявления переменных меняются, потому что типы по умолчанию становятся non-nullable:
// In null-safe Dart, none of these can ever be null.
var i = 42; // Inferred to be an int.
String name = getFileName();
final b = Foo();
Если вы хотите создать переменную, которая может содержать значение или null, вам необходимо это обозначить в описании переменной, добавив суффикс ? к типу:
// aNullableInt can hold either an integer or null.
int? aNullableInt = null;
Null safety реализована очень надёжно: статический анализ с множеством функциональных возможностей облегчает работу с nullable типами. К примеру, после проверки null, Dart повышает тип локальной переменной с nullable до non-nullable:
int definitelyInt(int? aNullableInt) {
 if (aNullableInt == null) {
   return 0;
 }
 // aNullableInt has now promoted to a non-null int.
 return aNullableInt;
}
Ещё мы добавили новое ключевое слово, required. Если обратиться к именованному параметру, обозначенному как required (что часто происходит в API виджетов во Flutter) и забыть предоставить аргумент, возникнет ошибка:
Поэтапная миграция на null safetyNull safety – фундаментальное изменение нашей системы типов. Чтобы избежать множества проблем, мы не переводим на него принудительно: вам решать, когда лучше мигрировать. Null safety – добровольный выбор: вы можете пользоваться Dart 2.12 и не обязаны при этом переходить на null safety. Вы даже можете использовать пакеты, уже поддерживающие null safety, независимо от того, поддерживает ваше приложение или пакет null safety или нет.Чтобы помочь вам с миграцией уже имеющегося кода на null safety, у нас есть инструмент для миграции и гайд по миграции. Сначала инструмент анализирует весь ваш код. Затем вы можете самостоятельно проверить допустимость значений null в обнаруженных случаях. Если вы не согласны с каким-то из результатов, можете добавить подсказку и таким образом изменить результат. Такие миграционные подсказки могут сильно улучшить качество миграции.
Пока что новые пакеты и приложения, собранные с dart create и flutter create, не поддерживают sound null safety. Мы планируем это исправить в будущем стабильном релизе, когда убедимся, что большая часть экосистемы мигрировала. Новый пакет или приложение можно легко перевести на null safety с помощью dart migrate.Статус миграции на null safety в экосистеме DartЗа последний год мы делали несколько превью и бета-сборок sound null safety, чтобы наполнить экосистему пакетами, поддерживающими null safety. Подготовительный этап крайне важен, так как мы рекомендуем мигрировать на sound null safety в определенном порядке: пакет или приложение следует переводить на null safety только после того, как мигрируют все их зависимости.Мы уже опубликовали null-safe-версии сотен пакетов от команд Dart, Flutter, Firebase и Material. Помимо этого нам невероятно помогло сообщество: более тысячи пакетов на pub.dev уже поддерживают null safety. Важно отметить, что самые популярные пакеты мигрировали первыми: 98% из 100 самых популярных пакетов, 78% из 250, и 57% из 500 уже перешли на поддержку null safety как раз к релизу. Мы надеемся, что в ближайшие недели на pub.dev появится ещё больше пакетов с null safety. Результаты нашего анализа показали, что подавляющее большинство пакетов на pub.dev уже разблокированы и могут начать процесс миграции.Преимущества sound null safetyКак только вы завершите миграцию, Dart станет абсолютно непротиворечивым (sound). Dart на 100% гарантирует, что переменные non-nullable типа не могут быть null. Когда Dart анализирует код и определяет переменную как non-nullable, эта переменная всегда будет non-nullable. Кроме Dart, sound null safety есть в Swift, но в целом таких языков программирования не очень много.Sound null safety в Dart имеет ещё один плюс: ваши программы смогут стать меньше и быстрее. Так как Dart уверен, что non-nullable переменные никогда не имеют значения null, онможет оптимизировать код. Например, Статический (AOT) компилятор Dart может генерировать более компактный и быстрый нативный код, потому что ему не надо добавлять проверку на nulls: он уже знает, что значение переменной не null.Dart FFI для интеграции Dart с библиотеками CDart FFI помогает эффективно использовать уже имеющийся в библиотеках C код, что улучшает переносимость и в то же время позволяет интегрировать хорошо отлаженный код на C в задачах, для которых критически важна производительность. На момент выхода Dart 2.12, Dart FFI перешел из бета-версии в стабильную и готов к применению в продакшн. Мы также добавили к нему несколько новых фич, включая вложенные структуры (struct) и возможность передавать структуры по значению.Передача структур по значениюВ коде на языке C структуры можно передавать как по ссылке, так и по значению. Раньше FFI поддерживал только передачу по ссылке, но начиная с Dart 2.12 можно передавать структуры и по значению. Приведу небольшой пример двух функций на C, в которых структура передаётся как по ссылке, так и по значению:
struct Link {
 double value;
 Link* next;
};
void MoveByReference(Link* link) {
 link->value = link->value + 10.0;
}
Coord MoveByValue(Link link) {
 link.value = link.value + 10.0;
 return link;
}
Вложенные структурыВ языке C API часто используют вложенные структуры. Они содержат внутри себя другие структуры. Пример:
struct Wheel {
 int spokes;
};
struct Bike {
 struct Wheel front;
 struct Wheel rear;
 int buildYear;
};
С выходом Dart 2.12 FFI поддерживает вложенные структуры.Изменения в APIДля перехода к стабильному FFI, а также для поддержки уже упомянутых фич, мы внесли несколько небольших изменений в API.Теперь создавать пустые структуры не разрешается (изменение без обратной совместимости #44622), и разработчик получает предупреждение о депрекации. Вместо пустых структур можно использовать новый тип, Opaque. В функциях dart:ffisizeOf, elementAt и ref теперь требуется использовать аргументы, тип которых определяется во время компиляции (изменение без обратной совместимости #44621). В package:ffi добавлены новые вспомогательные функции, чтобы выделить и освободить память в распространённых случаях. Теперь больше не требуется дополнительного бойлерплейта:
// Allocate a pointer to an Utf8 array, fill it from a Dart string,
// pass it to a C function, convert the result, and free the arg.
//
// Before API change:
final pointer = allocate<Int8>(count: 10);
free(pointer);
final arg = Utf8.toUtf8('Michael');
var result = helloWorldInC(arg);
print(Utf8.fromUtf8(result);
free(arg);
// After API change:
final pointer = calloc<Int8>(10);
calloc.free(pointer);
final arg = 'Michael'.toNativeUtf8();
var result = helloWorldInC(arg);
print(result.toDartString);
calloc.free(arg);
Автоматическая генерация биндингов в FFIВ случае с большими API очень много времени может уйти на то, чтобы написать в Dart биндинги, интегрирующиеся с кодом на C. Чтобы сделать вашу жизнь проще, мы собрали генератор биндингов, который автоматически создает обёртки FFI из заголовочных файлов на C. Предлагаем вам попробовать, что получилось: package:ffigen.План развития FFIТеперь, когда основная часть FFI платформы готова, мы хотим добавить к набору фич FFI фичи, которые будут накладываться на основу платформы. Вот несколько интересующих нас фич: Примеры использования FFIНам встречалось много интересных способов применения Dart FFI для интеграции с различными API на основе языка C. Вот несколько примеров:
  • open_file один API, с помощью которого можно открывать файлы на нескольких платформах. С помощью FFI он вызывает API на нативной ОС (Windows, macOS и Linux).
  • win32 оборачивается вокруг большинства распространённых API Win32, благодаря чему можно вызывать целый ряд API Windows непосредственно из Dart.
  • objectbox – «быстрая» база данных, поддерживаемая кодом на C.
  • tflite_flutter с помощью FFI даёт Dart доступ к TensorFlow Lite API.
Чего ждать от языка Dart в будущем?Sound null safety – самое крупное из изменений, внесённых в язык Dart за последние несколько лет. Мы хотим постепенно вносить чуть менее масштабные изменения в язык и платформу, опираясь на уже имеющийся крепкий фундамент. По ссылке можете посмотреть, с чем мы сейчас экспериментируем в проекте по разработке языка.Псевдонимы типов (type aliases) (#65): Возможность создавать псевдонимы других типов, помимо функций. Например, создавать typedef и использовать его как переменную:
typedef IntList = List<int>;
IntList il = [1,2,3];
Оператор тройного сдвига (triple-shift operator) (#120): новый, полностью переопределяемый оператор >>>, с помощью которого можно будет побитово сдвигать беззнаковые целые числа.Мета-аннотации дженерики (Generic metadata annotations) (#1297): дополнение мета-аннотаций аннотациями, содержащими аргументы типа.Статическое метапрограммирование (Static meta-programming) (#1482): поддержка статического метапрограммирования — программ на Dart, производящих новый исходных код Dart в процессе компиляции, аналогично макросам для Rust и function builder-ам в Swift. Эта фича пока на начальном этапе исследования. По нашему мнению, с её помощью можно будет воплотить пользовательские сценарии, которые сегодня полагаются на автоматическую кодогенерацию.Dart 2.12 уже доступенDart 2.12 с поддержкой sound null safety и стабильным FFI уже можно использовать в SDK Dart 2.12 и Flutter 2.0. Но сначала просим вас ознакомиться с известными проблемами при миграции на null safety в Dart и во Flutter. Если вы столкнулись с не упомянутой нами проблемой, пожалуйста, сообщите о ней в Dart issue tracker.Если вы разрабатывали пакеты, опубликованные на pub.dev, просим вас сегодня же ознакомиться с руководством по миграции и изучить, как мигрировать на sound null safety. Если вы переведете свой пакет на null safety, скорее всего, это поможет разблокировать другие зависящие от него пакеты и приложения. Также хотим выразить огромную благодарность тем, кто уже мигрировал!Нам очень интересно узнать о вашем опыте работы с sound null safety и FFI. Пожалуйста, оставьте комментарий или напишите нам в Твиттере: @dart_lang.
===========
Источник:
habr.com
===========

===========
Автор оригинала: Майкл Томсен
===========
Похожие новости: Теги для поиска: #_programmirovanie (Программирование), #_razrabotka_mobilnyh_prilozhenij (Разработка мобильных приложений), #_dart, #_flutter, #_flutter, #_dart, #_mobilnaja_razrabotka (мобильная разработка), #_programmirovanie (программирование), #_perevod (перевод), #_krossplatformennaja_razrabotka (кроссплатформенная разработка), #_razrabotka_mobilnyh_prilozhenij (разработка мобильных приложений), #_surf, #_surfstudio, #_blog_kompanii_surf (
Блог компании Surf
)
, #_programmirovanie (
Программирование
)
, #_razrabotka_mobilnyh_prilozhenij (
Разработка мобильных приложений
)
, #_dart, #_flutter
Профиль  ЛС 
Показать сообщения:     

Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете голосовать в опросах
Вы не можете прикреплять файлы к сообщениям
Вы не можете скачивать файлы

Текущее время: 22-Ноя 09:27
Часовой пояс: UTC + 5