Основы Flutter
220 subscribers
8 photos
16 links
Канал авторского коллектива книги "Основы Flutter"

Электронная версия книги на платформе Stepik с тестами и интерактивными задачами на программирование (только Dart) - https://stepik.org/a/197817
Download Telegram
🚨Обновление "Основы Flutter (в разработке)" 🥳

В курс на Stepik перенесен раздел из 8-й главы книги, который не увидит свет в печатной версии - "Работа с анимацией" (см. подробности) и сквозной проект к главе 🔫

В связи с добавленным за последние пару месяцев объемом материалов, цена курса увеличивается до 2999 рублей. Если вы хотели его приобрести, но все никак не было "времени", по 8-е мая это можно будет сделать по старой цене, воспользовавшись скидкой 🫣
Please open Telegram to view this post
VIEW IN TELEGRAM
🚨Обновление "Основы Flutter (в разработке)" 🥳

В курс на Stepik перенесена 9-я, последняя глава книги - "Сборка приложения" ^_^ Постепенно модули курса будут дополнены проверочными тестами для закрепления пройденного материала, что ознаменует завершение работы над ним на платформе Stepik 🔫 Т.е. его текущее состояние состояние можно рассматривать как rc-1 (release candidate)

Т.к. на Stepik добавлена последняя глава, вы, наверное, уже догадались, что работа над печатной версией книги завершена и стартовал процесс переговоров с издательством, компаниями-партнерами, которые хотят поддержать издание печатной версии и т.д. А это значит, что впереди у нас ламповый стрим авторского коллектива с ответами на вопросы😎

p.s. Ставите "напоминалки" в календарь на 17-е мая (суббота) на 11 часов по Мск 👀
Please open Telegram to view this post
VIEW IN TELEGRAM
Из-за ряда обстоятельств стрим переносится на неделю - 24.05.2025 (суббота в 11 по мск).

p. s. Добавили комментарии ;)
🚨Стрим 24.05 (суббота) в 11 по мск

Напоминаем, что завтра состоится ламповый стрим авторского коллектива книги "Основы Flutter" с ответами на вопросы 😎

p.s. Ссылку для подключения скинем в канал перед началом стрима ;)
Please open Telegram to view this post
VIEW IN TELEGRAM
❤️ Спасибо всем кто был на стриме

На превью я угагатываюсь с вопроса про "визуальный оргазм" от Flutter

📱 Для тех кто не смог присутсвовать онлайн - доступна запись трансляции

Я по горячим следам накидал таймкоды, ведь мы затронули кучу полезных тем
Please open Telegram to view this post
VIEW IN TELEGRAM
В воскресенье (8.06.025) в 20:00 один из авторов "Основы Flutter" (Станислав Чернышев) проведет на своем ютуб-канале стрим с очень говорящим названием: "Геморройно-плагинная архитектура в Dart и Flutter приложениях"🫠

В его основе будет лежать доклад с Mobius 2025 Spring, где есть обзор различных способов добавления динамического поведения в приложения и мало кому известный подход с изоляционно-плагинной архитектурой на Dart. Дополнительно к этому вас будет ждать разбор кода экспериментальных возможностей Dart по подключению динамических модулей (пока пощупать нельзя 😭😭😭, только любоваться) 🔫

https://www.youtube.com/watch?v=9dcedxoq4bg
Please open Telegram to view this post
VIEW IN TELEGRAM
Стартуем стрим по "Геморройно-плагинная архитектура в Dart и Flutter приложениях"🫠

https://youtube.com/live/9dcedxoq4bg?feature=share

p.s. Запись стрима будет доступна только на Boosty, так что лучше не пропускать ;)
📢 Новые фичи в Dart 3.9

Начиная с Dart 3.9 по умолчанию будет включен экспериментальный флаг getter-setter-error. Он внесет изменение в то, как компилятор Dart обрабатывает ошибки, связанные с геттерами и сеттерами. На данный момент, если тип аргумента сеттера не совпадает с возвращаемым геттером типом данных:
class Person {
int _age = 0;

int get age => _age;

set age(String value){
var temp = int.tryParse(value);
if (temp != null){
_age = temp;
}
}
}


Это приводит к ошибке: "The return type of getter 'age' is 'int' which isn't a subtype of the type 'String' of its setter 'age'." С Dart 3.9 такой код больше не будет считаться ошибкой и может быть собран:
main() {
var person = Person();
print(person.age); // 0
person.age = "10";
print(person.age); // 10
}


Еще одним новшеством будет флаг sound-flow-analysis, который изменит работу анализа потока (flow analysis) с акцентом на sound-null-safety.

До текущего момента компилятор всегда проявлял осторожность, даже если тип переменной не допускал null. То есть, анализатор мог по-прежнему считать, что значение может быть null. Из-за такого поведения следующий код не соберется:
main() {
var x = 0;
String y;
if (x != null) y = 'feature enabled';
print(y);
// Error: The non-nullable local variable 'y'
// must be assigned before it can be used.
}


Это связано с тем, что анализатор считает, что ветка if не гарантирует исполнение и поэтому выдает ошибку о том, что переменная y возможно не проинициализирована. Dart 3.9 исправляет эту ситуацию и, по своей сути, ставит жирную точку в развитии анализатора Dart: от устаревшей смешанной модели (начиная с Dart 2.12) к строгому sound-null-safety анализу потока (первые шаги были сделаны в Dart 3). Теперь анализ кода будет более точным, что избавит нас от ложных ошибок, а также позволит на уровне компилятора (и подсвечиваемых кусков кода анализатором) убрать мертвые ветки кода во время сборки (разработки) .

Нужны ли нам эти фичи в Dart 3.9?
👍 – О, да, детка!!!
👌 – Сомнительно, но Окей
👎 – Отстой!
🚨Обновление "Основы Flutter: путь от Новичка до Профи" 🥳

В курс на Stepik добавлены тесты к главе про навигацию 🔫
Please open Telegram to view this post
VIEW IN TELEGRAM
📢 Новая фича в Dart: Static Enough Metaprogramming

PR от Славы Егорова по более простой реализации статического метапрограммирования в Dart был прият и теперь красуется в репозитории спецификации языка 🥳

🥲 Почему появилась эта спецификация?

Многие же из вас знают печальную историю с тем, как команда Dart жидко обделались с макросами и насколько кастрирован dart:mirrors?😢 Рефлексия - довольно мощная, но сложная и медленная штука, которая плохо совместима с AOT-компиляцией. Из-за этой особенности было принято решение полностью отказаться от возможности хоть как-то использовать эту встроенную библиотеку в продакшене.

Казалось бы - ну и что? Жили же с кодогенерацией без макросов и рефлексии!!! Но она требует отдельной инфраструктуры, усложняет разработку и не всегда удобна. Поэтому потребность в метапрограммировании до сих пор остается 😄

🧩 Новая спецификация предлагает:

👉 Введение аннотации @konst, указывающей компилятору выполнить вычисления на этапе компиляции.
👉 Возможность интроспекции структуры программы прямо во время компиляции.
@konst
final String data = computeData(); // вычислится при компиляции


Говоря более простым языком - разработчики смогут использовать часть Dart-кода, который ранее был невозможен в константных выражениях (циклы, условные операторы, списки и таблицы/карты).

⚡️ Что изменится?

Появятся Const-выражения (привет constexpr из С++):
@konst
final attributes = buildAttributes();


Дженерики смогут компилироваться в конкретные реализации:
void foo<@konst T>(T value) {}

foo(42); // на этапе компиляции создаст конкретную реализацию foo<int>


Циклы будут раскрываться при компиляции:
for (@konst final v in [1, 2, 3]) {
print(v); // на этапе компиляции развернётся в print(1); print(2); print(3);
}


🎯 Практическое применение
Если фича релизнится, то такие вещи, как JSON-сериализация, генерация метода hashCode и operator==, или автоматическая маршрутизация запросов можно будет реализовать прямо внутри Dart без дополнительного кодогена, что положительно скажется на точке G вашего проекта, т.к. значительно сократится количество файлов "*.g.dart"
mixin DataClass<@konst T> {
@override
operator ==(Object? other) {
if (other is! T) {
return false;
}

final typeInfo = TypeInfo.of<T>();
for (@konst final field in typeInfo.fields) {
final value1 = field.getFrom(this as T);
final value2 = field.getFrom(other);
if (field.type.isSubtypeOf<List>()) {
if ((value1 as List).length != (value2 as List).length) {
return false;
}
for (var i = 0; i < value1.length; i++) {
if (value1[i] != value2[i]) {
return false;
}
}
} else if (value1 != value2) {
return false;
}
}
return true;
}

@override
int get hashCode {
final typeInfo = TypeInfo.of<T>();
var hash = HashHelpers._seed;
for (@konst final field in typeInfo.fields) {
hash = HashHelpers.combine(hash, field.getFrom(this as T).hashCode);
}
return HashHelpers.finish(hash);
}

Map<String, Object?> toJson() => toJsonImpl<T>(this as T);
}


// Example
class A with DataClass<A> {
final int a;
final String b;
// ...
}



Уже видите профит от этой Static Enough Metaprogramming?

👍 – О, да, детка!!!
👌 – Сомнительно, но Окей
👎 – Отстой! (Не превращайте Dart в C++)
Please open Telegram to view this post
VIEW IN TELEGRAM