Когда в Dart (Flutter) лучше использовать ключевое слово const?

Ответ

В Dart и Flutter я использую const для создания констант времени компиляции. Это не только про неизменяемость, но и про производительность.

Основные случаи использования:

  1. Виджеты и их параметры: Если виджет и все его дочерние виджеты могут быть const, Flutter может не перестраивать их при ребилде дерева. Это критично для производительности.

    // Хорошо - всё const
    const SizedBox(
      width: 16.0,
      child: const Text('Заголовок', style: const TextStyle(fontSize: 14)),
    );
    
    // Плохо - виджет будет пересоздаваться каждый раз
    SizedBox(
      width: 16.0,
      child: Text('Заголовок', style: TextStyle(fontSize: 14)),
    );
  2. Константные коллекции и значения: Для неизменяемых списков, карт, цветов, стилей, которые используются в нескольких местах.
    static const List<String> supportedLanguages = ['en', 'ru'];
    static const defaultPadding = const EdgeInsets.all(16.0);

Когда НЕ использовать const:

  • Для объектов, которые зависят от данных времени выполнения (runtime).
  • Если конструктор класса не помечен как const.

Отличие от final:

  • final гарантирует, что переменная будет инициализирована один раз (в runtime), но не делает её константой времени компиляции. const — это final, но вычисляемое на этапе компиляции.

Ответ 18+ 🔞

Э, слушай, давай про const в Dart'е поговорим, а то народ часто нихуя не понимает, где его впендюрить. Это не просто какая-то мудя про "неизменяемость", это реально про производительность, ёпта.

Короче, где его пихать, чтобы не было мучительно больно:

  1. Виджеты, блядь. Это самое главное. Если виджет и всё, что внутри него, может быть const, Flutter просто берёт и не перестраивает его при каждом обновлении экрана. Представь, у тебя статичный блок с текстом — зачем его каждый раз создавать заново? Это же овердохуища лишней работы.

    // Вот так — красиво и быстро. Всё const, всё закешировано.
    const SizedBox(
      width: 16.0,
      child: const Text('Заголовок', style: const TextStyle(fontSize: 14)),
    );
    
    // А вот так — пиздопроебибна. Каждый ребилд — новый объект, зря память и процессор грузятся.
    SizedBox(
      width: 16.0,
      child: Text('Заголовок', style: TextStyle(fontSize: 14)),
    );
  2. Всякие списки, отступы, стили. Если ты где-то в коде захардкодил EdgeInsets.all(16.0) и используешь это в десяти местах, то без const у тебя будет десять разных объектов. А с const — один на всех. Экономия, ядрёна вошь!
    static const List<String> supportedLanguages = ['en', 'ru']; // Один список на всю программу
    static const defaultPadding = const EdgeInsets.all(16.0); // Один объект отступа

А когда его НЕ НАДО лепить?

  • Когда объект зависит от того, что происходит во время работы программы (runtime). Ну, там DateTime.now() или данные из сети. Компилятор же не ясновидящий, чтобы это заранее вычислить.
  • Если конструктор класса не помечен как const. Тут уж ничего не поделаешь, иди к автору библиотеки и ругайся.

Чем const от final отличается, а? Вот тут многие путаются, волнение ебать. final — это типа "ладно, присвоил один раз и хватит", но это происходит уже когда программа работает. А const — это жёстче. Это значение известно прямо когда ты код компилируешь, и оно одно на всех. Грубо говоря, каждый const — это final, но не каждый final — это const. Если можешь сделать const — делай, чувак, не бзди.