Flutter: Null Safety
As a developer, we always struggle to handle NullPointerException which causes a lot of time and money while developing software. It has been referred to as a billion-dollar mistake. (Wiki)
Flutter 2 supports null safety. You can now migrate your Flutter packages to use non-nullable types. Follow the below link to perform flutter migration for old projects.
Note: To use it it’s necessary to have your all libs updated with a null safety feature, otherwise you can’t migrate your project to Flutter 2.
Dart distinguishes between nullable and non-nullable references as a part of its type system which helps in eliminating the risk of NullPointerException.
In Dart, all variables are non-nullable by default. We cannot assign a null value to a variable because it’ll throw a compilation error:
Null safety is a major new productivity feature that helps you avoid null exceptions, a class of bugs that are often hard to spot. As an added bonus, this feature also enables a range of performance improvements.
Compile Time Error For Nullable Type.
Variables are non-nullable by default which means every variable should be assigned and cannot be null.
Values must be assigned at the time of declaration otherwise we have to mark it as nullable using ‘?’ Also, it is not possible to assign a value null to the variable, it will give an error “A country of type ‘Null’ can’t be assigned to a variable of type ‘String’.”
The below code will work, as the variable country is not used before assigning a value.
Below code gives us an error as we are using a variable before it got assigned value, and the error which thrown “The non-nullable local variable ‘value’ must be assigned before it can be used.”
Nullable types (Use Question Mark ‘?’)
To force variable nullable use ‘?’ like below, which tells the system that it can be null, and assigned letter. This will through null exception which results in a red screen on mobile.
late variables
The keyword late can be used to mark variables that will be initialized later, i.e. not when they are declared but when they are accessed. This also means that we can have non-nullable instance fields that are initialized later: Accessing value before it is initialized will throw a runtime error.
late final
Wow. isn’t these amazing, Final variable can be assigned a letter.
You can declare a late final without an initializer, which is the same as having just a late variable, but it can only be assigned once.
If the late final is declared as static, then it will be evaluated at runtime.
This error will be thrown at runtime, not at the compile-time, so don’t declare final late values again, this will cause a runtime error.
The cascade operator helps us to verify whether the given object/variable is null or not if it’s null then we can use another value, it’s more like if, else
I have tried to put everything below the class file, respectively wrote test cases for it.
Подготовка экосистем Dart и Flutter к переходу на null safety
Поезд null safety мчится вперёд, уже почти официально анонсирован Flutter 2.0 (подключайтесь к предстоящему Flutter Engage), экосистема Dart тоже не стоит на месте. Мы перевели на русский язык новость из официального блога Dartlang и настоятельно рекомендуем вам переводить свои пакеты на новые рельсы, если вы этого ещё не сделали!
Вышел стабильный API для null safety
На днях вышла новая бета версия Dart, которая отличается повышенной стабильностью и наличием надежной null safety системы, над которой мы работали больше года. Обновленная бета (2.12.0–259.9.beta) доступна на dart.dev и на бета канале Flutter. До выхода стабильной версии null-safe Dart критических изменений больше не предвидится.
Мы призываем разработчиков публиковать null-safe версии своих пакетов, чтобы пользователи смогли получить полноценную функциональность экосистемы на момент публикации стабильной версии null-safe Dart. Сами мы этот процесс уже запустили — опубликовали стабильные версии null-safe пакетов, таких как args, yaml и grpc. Если все ваши зависимости в null-safe состоянии и опубликованы под стабильной версией (например, 1.0.0 вместо 1.0.0-nullsafety.123), вам пора заняться тем же!
На pub.dev мы также добавили новую фичу, которая сама размечает версии пакетов, помечая preview-релизы, если стабильная версия зависимого Dart SDK еще не вышла. Preview-релизы будут автоматически помечены как стабильные версии, как только состоится релиз стабильного Dart SDK.
Cтабильная (1.6.0) и preview (2.0.0) версии пакета args на pub.dev
В руководстве по переходу на null safety есть вся последняя информация о том, как организовать миграцию ваших пакетов. Обратите особое внимание на ограничения Dart SDK и версии ваших зависимостей в pubspec. В том числе обратите внимание и на версию SDK, который вы используете для тестирования непрерывной интеграции (CI). Стабильная null-safe версия Dart выйдет уже скоро! Спасибо вам за поддержку!
Null safety в Dart
Привет, Хабр! Представляю вашему вниманию перевод статьи «Announcing sound null safety» автора Filip Hracek с моими комментариями:
Null safety — безопасная работа с пустыми ссылками. Далее по тексту для краткости и по причине устойчивости термина будет использоваться английское наименование null, null safety. Да и перевод «нулевая безопасность» наводит совсем на противоположные мысли.
sound — в данном контексте (sound null safety) можно перевести как «надежный».
Если есть предложения по улучшению перевода или нашли ошибки — пишите в личку, постараемся исправиться.
Наступил важный этап для команды Dart с их представлением технического превью наработок по null safety. Null safety позволяет избежать целого класса ошибок, которые часто трудно обнаружить, а в качестве бонуса обеспечивает ряд улучшений производительности. На данный момент мы выпустили предварительное техническое превью и ждем от вас обратной связи.
В этой статье мы раскроем планы команды Dart по развертыванию null safety, а также объясним, что скрывается за термином Sound null safety, и чем этот подход отличается от других языков программирования.
Описываемая версия была представлена 10-го июня 2020 года.
Зачем нужна null safety?
Dart — типобезопасный (type-safe) язык. Это означает, что когда вы получаете переменную некоторого типа, компилятор может гарантировать, что она принадлежит ему. Но безопасность типов сама по себе не гарантирует, что переменная не равна null.
Null-ошибки встречаются часто. Поиск на GitHub находит тысячи репортов (issue), вызванных нулевыми значениями в Dart-коде, и еще больше коммитов, пытающихся решить эти проблемы.
Попробуйте обнаружить проблему обнуления ссылки в следующем примере:
Эта функция, безусловно, завершится ошибкой, если вызывается с обнуленным параметром, но есть и второй случай, который следует рассмотреть:
Null safety устраняет эту проблему:
С null safety вы можете с большей уверенностью опираться на свой код. Не будет больше надоедливых ошибок обращения к обнуленной переменной во время выполнения. Только статические ошибки в момент компиляции кода.
Если быть совсем честными, то текущая реализация все же оставляет несколько возможностей словить null-ошибки в момент выполнения, о них чуть позже.
Sound (надежная) null safety
Немного спорное заявление, которое заставило меня копнуть в эту тему немного глубже, чтобы понять, как реализуется null safety в разных языках. В итоге я сравнил эти реализации в Swift, Kotlin и Dart. Результат этих изысканий можно посмотреть на записи нашего внутрикомандного доклада.
Подобная надежная реализация null safety в Dart имеет еще одно приятное следствие: это означает, что ваши программы могут быть меньше и быстрее. Поскольку Dart действительно уверен, что переменные никогда не могут быть обнулены, Dart может оптимизировать результат компиляции. Например, AOT-компилятор может создавать меньший и более быстрый нативный код, поскольку ему не нужно добавлять проверки на пустые ссылки.
Мы видели некоторые очень многообещающие предварительные результаты. Например, мы увидели улучшение производительности на 19% в микробенчмарке, который эмулирует типичные шаблоны рендеринга в инфраструктуре Flutter.
Основные принципы
Прежде чем приступить к детальному проектированию null safety, команда Dart определила три основных принципа:
Необнуляемость по-умолчанию. /** Часто можно увидеть в виде абревиатуры NNBD в документации **/ Если вы явно не скажете Dart’у, что переменная может быть обнулена, он сочтет ее необнуляемой. Мы выбрали это как значение по умолчанию, потому что обнаружили, что в API ненулевое значение на текущий момент является наиболее распространенным. /** Вероятно, речь идет о переработке текущего API Flutter **/.
Поэтапная применимость. Мы понимаем, что должна существовать возможность постепенного перехода к null safety шаг за шагом. На самом деле, нужно иметь обнуляемый и null safety код в одном проекте. Для этого мы планируем предоставить инструменты, помогающие с миграцией кода.
Полная надежность (sound). Как упоминалось выше, null safety в Dart надежна. Как только вы преобразуете весь свой проект и ваши зависимости на использование null safety, вы получите все преимущества надежности.
Объявление переменных с null safety
Основной синтаксис достаточно прост. Ниже приведен пример объявления различных переменных. Обратите внимание, что по умолчанию используются необнуляемые переменные, поэтому они выглядят как прежде, но их значение не может быть обнулено.
Dart позаботится о том, чтобы вы никогда не присваивали значение null ни одной из перечисленных выше переменных. Если вы попытаетесь выполнить i = null даже тысячу строк спустя, вы получите ошибку статического анализа и красные волнистые линии — ваша программа откажется компилироваться.
Если вы хотите, чтобы ваша переменная могла обнуляться, вы можете использовать ‘?’ вот так:
Перечисленные выше переменные ведут себя точно так же, как и все переменные в актуальной версии Dart.
‘?» можно также использовать в прочих местах:
Но, опять же, хотелось бы, чтобы вам почти никогда не придется использовать ‘?’. Подавляющее большинство ваших переменных будут необнуляемыми.
Упрощение использования null safety
Команда Dart изо всех сил старается сделать null safety максимально простой в использовании. Например, посмотрите на этот код, который использует if, чтобы проверить нулевое значение:
Обратите внимание, что Dart достаточно умен, чтобы понять, что к тому времени, когда мы пройдем оператор if, переменная loudness не может иметь значение null. И поэтому Dart позволяет нам вызывать метод clamp() без лишних танцев с бубном. Это удобство обеспечивается так называемым анализом потока выполнения (flow analysis): анализатор Dart просматривает ваш код, как если бы он выполнял его, автоматически выясняя дополнительную информацию о вашем коде.
Flow analysis, уже существующая фича языка Dart, используется, например, при проверке соответствия типа. В данном случае они переиспользовали ее для null safety, что позволяет смотреть на отношения типа и опционального типа как на наследование:
Вот еще один пример, когда Dart может быть уверен, что переменная не равна null, так как мы всегда присваиваем ей значение:
Анализ потока выполнения работает только внутри функций. Если у вас есть глобальная переменная или поле класса, то Dart не может гарантировать, что ему будет присвоено значение. Dart не может моделировать поток выполнения всего вашего приложения. По этой причине вы можете использовать новое ключевое слово late, если знаете, что переменная будет инициализирована на момент первого к ней обращения, но не можете инициализировать ее в момент объявления.
Обратите внимание, что v не может быть обнулена, хотя изначально не имеет значения. Dart считает, что вы не будете пытаться прочитать v, пока ему не будет присвоено ненулевое значение, и ваш код компилируется без ошибок.
А вот и он — момент для выстрела себе в ногу.
Опасный костыль, который будет главным признаком пахнущего кода. Ситуацию усугубляет еще и то, что нет возможности проверить состояние переменной. Команда Dart обсуждала такую возможность, но пришла к выводу, что на данном этапе проще не реализовывать проверки, как, например, в Kotlin через рефлексию.
Второе спорное решение — это интеграция знакомого всем Swift-программистам восклицательного знака, то есть, теперь можно будет делать force unwrap в Dart.
В обоих случаях (с late и ‘!’) мы сможем при неправильном использовании получить ошибку в момент выполнения программы.
Также стоит упомянуть в контексте late еще одно нововведение, которое почему-то скрывается в статьях и видео от команды Dart. Добавлено новое ключевое слово ‘required’ для именованных параметров конструктора. Это уже знакомый ‘@required’, только не из отдельного пакета и без собачки.
Обратная совместимость
Команда Dart работала больше года, чтобы довести null safety до уровня технического превью. Это самое большое изменение языка со времен релиза второй версии. Тем не менее, это изменение, не ломающее обратную совместимость. Существующий код может вызывать код с null safety и наоборот. Даже после полноценного релиза null safety будет дополнительной опцией, которую вы сможете использовать, когда будете готовы. Ваш существующий код продолжит работать без изменений.
Эти бы слова, да разработчикам Swift в уши, особенно 3-й версии…
Но даже тут не так все радужно, разработчики сами говорят, что при совмещении null safety кода и «старого» кода в одном проекте они не могут гарантировать надежность (soundness) системы типов.
Дальнейший план действий
Мы планируем развернуть null safety постепенно в три этапа:
Начни уже сейчас
Самый быстрый способ попробовать null safety уже сегодня — это nullsafety.dartpad.dev — версия DartPad с включенной функцией null safety. Откройте раскрывающийся список «Learn with Snippets», чтобы найти серию обучающих упражнений, описывающих новый синтаксис и основы null safety.
Также можно поэкспериментировать с null safety в небольших консольных приложениях (мы еще не обновили более крупные фреймворки, такие как Flutter). Для начала нужно загрузить Dart SDK с dev-ветки, затем можно скачать этот пример консольного приложения. В README файле есть инструкции по запуску приложения с включением экспериментальной функции null safety. Другие файлы в примере предоставляют конфигурации запуска, которые позволят выполнять отладку в VS Code и Android Studio.
Также можно ознакомиться с документацией (в дальнейшем появится еще):
Спасибо за то, что дочитали до конца. Перевод немного запоздал, но, надеюсь, комментарии привнесли пользы материалу и это не стало просто переводом один в один. От себя хочется добавить, что эта фича — действительно полезный шаг вперед для всей экосистемы Flutter. Жду с нетерпением, чтобы начать использовать уже на живых приложениях. А пока, как говорится на забугорском, stay tuned!
Релиз Dart 2.10: на шаг ближе к null-safety

Команда языка Dart постепенно приближается к одному из самых мажорных релизов — null-safety. Эта фича есть у многих лидеров рынка, включая Kotlin и TypeScript. По понятным причинам этот релиз нельзя сделать в виде рубильника: одним днём и простым апдейтом. Набравшее скорость сообщество, выпустившее огромное количество пакетов, уже не сможет перейти на мажорную версию по щелчку пальцев. Поэтому процесс этот поступательный и не такой быстрый, как хотелось бы. Тем не менее сомневаться в том, что уже довольно скоро язык станет значительно лучше и удобнее, не приходится!
Мы в Wrike не смогли обойти стороной обновление релиз Dart 2.10 и переводим статью из официального блога Dartlang.
Новый, унифицированный dart для всех ключевых задач. А также апдейт по таймлайну null-safety и принципах миграции.
Авторы: Майкл Томсен и Кевин Мур
Сегодня мы анонсируем новый Dart, версия 2.10 (two-dot-ten). В этом релизе представлен новый унифицированный Dart: единый инструмент для всех возможных задач разработчика, таких как создание проектов, анализ и форматирование кода, тестирование и компиляция приложений. У нас есть обновленная информация об этапах работ по null-safety, а также принципы миграции существующего кода.
Новый унифицированный инструмент разработчика Dart
О null-safety
Мы хорошо поработали с null-safety с тех пор, как несколько месяцев назад запустили первую техническую превью. В полной null-safety мы видим инструмент предотвращения трудно обнаруживаемых null-ошибок, а также дополнительный бонус к улучшению производительности. Если хотите узнать больше, рекомендуем нашу новую страницу Understanding null safety. Если предпочитаете короткое видео, посмотрите the null safety video с мероприятия Flutter Day, прошедшего несколько месяцев назад.
Когда null-safety будет готова к использованию? Вот наш прогноз:
Работа Flutter с техническим превью 2: Мы успешно перенесли большую часть Flutter. Ожидаем, что скоро — вероятно, в течение следующего месяца — среда Flutter будет полностью перенесена, и, таким образом, мы будем готовы к экспериментальному использованию Flutter. Вы сможете попробовать null-safety во Flutter и выполнить пробную миграцию ваших приложений и пакетов Flutter. Вам нужно будет использовать экспериментальный флаг. Не используйте экспериментальные функции в продакшне и не публикуйте перенесенные пакеты.
Ранняя миграция пакетов с помощью бета-версии: позже в этом году мы завершим улучшение производительности и обеспечим достаточное количество тестов, чтобы быть уверенными, что функция работает должным образом и что обратная совместимость надежна. К тому времени мы опубликуем бета-версию этой функции, и вам не нужно будет передавать экспериментальный флаг. Надеемся, что владельцы пакетов начнут их миграцию в null-safety, тем самым проведя последний раунд проверки, насколько эта функция готова к стабильному выпуску.
Использование в продакшне stable: в зависимости от обратной связи на запуск бета-версии мы исправим все оставшиеся проблемы, а затем опубликуем их в stable. Трудно назвать конкретные сроки, но мы думаем о начале следующего года. Как только эта функция станет стабильной, мы надеемся на широкое внедрение null safety приложениями, опубликованными в сторах, и многими и пакетами, опубликованными в pub.dev в стабильных версиях.
Принципы перехода к null-safety
Мы хотели бы поделиться нашими главными принципами для миграции на null-safety.
Переходите, когда будете готовы
Null-safety — это фундаментальное изменение в системе Dart. Это меняет основы объявления переменных, потому что мы решили сделать переменные ненулевыми по умолчанию:
Такое фундаментальное изменение было бы разрушительным, если бы мы настаивали на принудительном переходе. Мы хотим, чтобы вы сами выбрали подходящее время, поэтому null-safety — это опциональная функция: вы можете использовать последние версии Dart и Flutter без необходимости включать null-safety. Вы даже можете иметь зависимость между пакетами с уже включенной null-safety и приложениями или пакетами, которые ее еще не подключили.
Переходите постепенно, по порядку
Мы настоятельно рекомендуем переносить код по порядку, начиная с “листьев” графа зависимостей. Например, если C зависит от B, который зависит от A, сначала перенесите в null-safety A, затем B, затем C. Этот порядок применяется независимо от того, являются ли A, B и C библиотеками, пакетами или приложениями.
Почему порядок так важен? Вы можете добиться некоторого успеха в переносе кода до миграции ваших зависимостей, но вы рискуете столкнуться с необходимостью повторной миграции, если ваши зависимости изменят свои API в процессе переноса. Мы предоставим инструменты, которые помогут вам узнать, какие из зависимостей были успешно перенесены. Если вы являетесь автором пакета, то, чтобы избежать риска нарушения API, подождите, пока все ваши зависимости не будут перенесены, прежде чем публиковать null-safe версию.
Используйте автоматизированные инструменты для снижения затрат на миграцию
Инструмент миграции интерактивен, поэтому вы можете просмотреть свойства, которые он определил. Если вы не согласны с каким-либо из выводов инструмента, можно добавить подсказки о допустимости пустых значений, чтобы изменить вывод. Например, если вы хотите сделать API не допускающим null, даже если потребуется некоторый рефакторинг, можно сообщить об этом инструменту и повторно запустить анализ миграции. Добавление всего нескольких подсказок по миграции может оказать огромное влияние на качество перехода.
Получите полную выгоду при полном использовании
Как только весь ваш код — и пакеты, от которых он зависит — будет перенесен, он может выполняться с гарантированной null-safety. До этого момента ваш код будет работать и компилироваться так же, как сейчас, но абсолютная null-safety обеспечит полную верификацию времени выполнения и оптимизацию компилятора. Выполнение тестов с полной null-safety поможет избежать проблем с присваиванием null во время выполнения, а компиляция приложений с null-safety гарантирует, что вы получите оптимизации сразу и в будущем, например, меньший по размеру скомпилированный вывод и более быстрое выполнение.
Дальнейшие действия
Скоро у нас будет больше новостей о null-safety. Скорее всего, в течение следующего месяца, когда наши друзья в команде Flutter будут иметь фреймворк Flutter с поддержкой null-safety, готовый к экспериментам. Следите за обновлениями в блоге Flutter. А пока вы можете поэкспериментировать с null-safe кодом Dart с помощью DartPad с null-safety и узнать больше о дизайне функции в документации по null-safety.
Dart 2.12: Sound null safety и Dart FFI отправлены на стабильный канал
Представляем вам перевод статьи, анонсирующей выход 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 safety
Sound null safety – самое масштабное дополнение к языку Dart с тех пор, как в Dart 2.0 появилась надежная система типов. Null safety делает систему типов ещё надёжнее. Она позволяет обнаруживать ошибки типа null error ещё в процессе разработки, а значит, вы избежите крашей, когда приложение выйдет в продакшн. Sound null safety базируется на нескольких ключевых принципах.
Non-nullable по умолчанию: фундаментальное изменение системы типов
До появления null safety основная проблема была в том, что тяжело заметить разницу между кодом, который ожидает значение null, и кодом, который не обрабатывает null.
Скриншот с результатом анализа в IDE
И это довольно простая ошибка. Когда мы ещё только начинали использовать null safety в коде Google, нам встречались куда более запутанные ошибки. О некоторых багах было уже годами известно, но наши команды не могли найти их причину без помощи дополнительных статических проверок от null safety. Вот несколько примеров:
В одной команде обнаружили, что часто проверяют на значения null те выражения, в которых в принципе не может быть null. Чаще всего с этой проблемой сталкивались в коде, использующем protobuf, где необязательные поля возвращают значение по умолчанию, если оно не задано, и не могут вернуть null. В результате код неправильно проверял условия по умолчанию: путал значение по умолчанию и значение null.
Члены команды Google Pay нашли баги в своём коде во Flutter, когда не смогли получить доступ к объектам Flutter State вне контекста Widget. До null safety такие объекты возвращали null и маскировали ошибку; с null safety глубокий анализ показал, что null не может быть значением в этом случае, и диагностировал ошибку ещё до этапа компиляции.
Работа с non-nullable по умолчанию
После перехода на null safety основы объявления переменных меняются, потому что типы по умолчанию становятся non-nullable:
Null safety реализована очень надёжно: статический анализ с множеством функциональных возможностей облегчает работу с nullable типами. К примеру, после проверки null, Dart повышает тип локальной переменной с nullable до non-nullable:
Поэтапная миграция на null safety
Null safety – фундаментальное изменение нашей системы типов. Чтобы избежать множества проблем, мы не переводим на него принудительно: вам решать, когда лучше мигрировать.
Null safety – добровольный выбор: вы можете пользоваться Dart 2.12 и не обязаны при этом переходить на null safety. Вы даже можете использовать пакеты, уже поддерживающие null safety, независимо от того, поддерживает ваше приложение или пакет null safety или нет.
Чтобы помочь вам с миграцией уже имеющегося кода на null safety, у нас есть инструмент для миграции и гайд по миграции.
Сначала инструмент анализирует весь ваш код. Затем вы можете самостоятельно проверить допустимость значений null в обнаруженных случаях. Если вы не согласны с каким-то из результатов, можете добавить подсказку и таким образом изменить результат. Такие миграционные подсказки могут сильно улучшить качество миграции.
Статус миграции на 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 с библиотеками C
Dart FFI помогает эффективно использовать уже имеющийся в библиотеках C код, что улучшает переносимость и в то же время позволяет интегрировать хорошо отлаженный код на C в задачах, для которых критически важна производительность. На момент выхода Dart 2.12, Dart FFI перешел из бета-версии в стабильную и готов к применению в продакшн. Мы также добавили к нему несколько новых фич, включая вложенные структуры (struct) и возможность передавать структуры по значению.
Передача структур по значению
В коде на языке C структуры можно передавать как по ссылке, так и по значению. Раньше FFI поддерживал только передачу по ссылке, но начиная с Dart 2.12 можно передавать структуры и по значению. Приведу небольшой пример двух функций на C, в которых структура передаётся как по ссылке, так и по значению:
Вложенные структуры
В языке C API часто используют вложенные структуры. Они содержат внутри себя другие структуры. Пример:
С выходом Dart 2.12 FFI поддерживает вложенные структуры.
Изменения в API
Для перехода к стабильному FFI, а также для поддержки уже упомянутых фич, мы внесли несколько небольших изменений в API.
Автоматическая генерация биндингов в FFI
В случае с большими API очень много времени может уйти на то, чтобы написать в Dart биндинги, интегрирующиеся с кодом на C. Чтобы сделать вашу жизнь проще, мы собрали генератор биндингов, который автоматически создает обёртки FFI из заголовочных файлов на C. Предлагаем вам попробовать, что получилось: package:ffigen.
План развития FFI
Теперь, когда основная часть FFI платформы готова, мы хотим добавить к набору фич FFI фичи, которые будут накладываться на основу платформы. Вот несколько интересующих нас фич:
Типы данных, специфичные для ABI интерфейса, вроде int, long, size_t (#36140)
Inline массивы в структурах (#35763)
Примеры использования 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 и использовать его как переменную:
Оператор тройного сдвига (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.





