Что такое Null в Dart?

Ответ

Null в Dart представляет собой отсутствие значения. С введением null safety (начиная с Dart 2.12 и Flutter 2.0) система типов стала строже, чтобы предотвратить ошибки времени выполнения из-за разыменования null.

Основные концепции:

  1. Non-nullable типы (по умолчанию): Переменная не может содержать null.
    String name = 'Alice'; // OK
    String name = null; // Ошибка компиляции
  2. Nullable типы (с ?): Явно указываем, что переменная может быть null.
    String? nickname; // Начальное значение null
    nickname = 'Bob'; // OK
    nickname = null; // OK
  3. Безопасный доступ и операторы:
    • ?. (Опциональный доступ): Выполняет операцию, только если объект не null.
      int? length = nickname?.length; // length будет null, если nickname null
    • ?? (Оператор если-null): Предоставляет значение по умолчанию.
      String displayName = nickname ?? 'Гость'; // Если nickname null, используем 'Гость'
    • ! (Оператор утверждения non-null): Говорим компилятору: "Я уверен, что здесь не null". Использовать с осторожностью.
      String definitelyNotNull = nickname!; // Runtime-ошибка, если nickname null
  4. Обязательные параметры (required): Гарантирует, что аргумент будет передан.
    void greet({required String name}) { ... }
    greet(name: 'Alice'); // OK
    greet(); // Ошибка компиляции

    Null safety делает код более предсказуемым и уменьшает количество runtime-исключений.

Ответ 18+ 🔞

Э, бля, слушай сюда, про этот ваш null в Dart. Ну, типа, это когда нихуя нет, пустота, вакуум, дыра в значении. А потом пришли умные дядьки и сказали: "А давайте-ка, ёпта, сделаем так, чтобы программа не падала в пизду каждый раз, когда кто-то лезет в эту пустоту". Так и родилась null safety, с версий Dart 2.12 и Flutter 2.0. Теперь система типов — просто стерва с характером, она тебе просто так в null не даст ткнуть носом.

Вот как это всё работает, ёбана:

  1. Типы по умолчанию (non-nullable): Тут всё строго. Если ты сказал, что это String, то это должна быть строка, а не пустое место. Подсовываешь null — получаешь ошибку компиляции прямо в лоб, как кирпичём.
    String name = 'Алиса'; // Нормально
    String name = null; // Ошибка компиляции. Ты чё, охренел?
  2. Типы, которые могут быть пустыми (nullable, с ?): Тут ты сам, как хитрая жопа, говоришь системе: "Расслабься, тут может быть и ничего". Ставишь вопросик и спишь спокойно.
    String? nickname; // Изначально — нихуя (null)
    nickname = 'Боб'; // Окей
    nickname = null; // Тоже окей, сам разрешил
  3. Инструменты для работы с этой хернёй:
    • ?. (Опциональный доступ): Умная штука. "Если там что-то есть — сделай дело, если нет — иди нахуй и верни null". Не лезет куда не надо.
      int? length = nickname?.length; // length будет null, если в nickname пусто. Без скандалов.
    • ?? (Оператор "если-нихуя"): Твоя палочка-выручалочка. "Если тут пусто, дай мне что-нибудь другое, а то волнение ебать".
      String displayName = nickname ?? 'Гость'; // Если nickname — пустота, то будет 'Гость'. Проще некуда.
    • ! (Оператор "я уверен, блядь!"): Опасная хуйня. Ты берёшь на себя всю ответственность и клянёшься компилятору, что тут не null. Если соврал — программа накроется медным тазом с красивым исключением. Пользоваться — как ходить по охуенно тонкому льду.
      String definitelyNotNull = nickname!; // Runtime-ошибка, если nickname null. Сам дурак.
  4. Обязательные параметры (required): Это когда ты говоришь функции: "Слушай, чувак, этот аргумент — святое, без него я нихуя не работаю". Не передашь — получишь по шапке от компилятора.
    void greet({required String name}) { ... }
    greet(name: 'Алиса'); // Идеально
    greet(); // Ошибка компиляции. Где имя, сука?

Короче, null safety — это не просто прихоть, это чтобы твой код не разваливался от каждого чиха. Сначала, конечно, мозг ебёт, когда всё надо продумывать, но потом привыкаешь и живешь спокойно, без неожиданных "ошибок разыменования null" посреди ночи. Доверия к коду — овердохуища.