Menu
Coddy logo textTech

Null-aware операторы

Часть раздела Объектно-ориентированное программирование путешествия по Dart на Coddy — урок 27 из 110.

Помимо ?. и !, Dart предоставляет дополнительные операторы, которые делают работу с nullable-значениями более лаконичной. Эти null-aware операторы помогают писать более чистый код при работе с потенциальными значениями null.

Оператор null-объединения ?? возвращает левое значение, если оно не равно null, в противном случае он возвращает правое значение:

String? nickname;
String displayName = nickname ?? 'Guest';
print(displayName);  // Guest

nickname = 'Alex';
displayName = nickname ?? 'Guest';
print(displayName);  // Alex

Оператор присваивания с проверкой на null ??= присваивает значение только в том случае, если переменная в данный момент равна null:

String? username;
username ??= 'Anonymous';
print(username);  // Anonymous

username ??= 'NewName';
print(username);  // По-прежнему Anonymous (не была null)

Вы можете объединять в цепочку оператор доступа с проверкой на null ?. для вложенных свойств:

String? city = user?.address?.city;  // Безопасно, даже если user или address равны null

Эти операторы хорошо сочетаются друг с другом. Например, вы можете обратиться к свойству, которое может принимать значение null, и указать значение по умолчанию:

String greeting = user?.name ?? 'Stranger';
// Если user равен null ИЛИ user.name равен null, использовать 'Stranger'

Использование этих операторов позволяет сохранить читаемость кода, обеспечивая при этом безопасность по отношению к null во всей программе.

challenge icon

Задание

Легко

Давайте создадим систему регистрации гостей, которая продемонстрирует, как операторы с поддержкой null могут сделать ваш код чище при обработке необязательной информации.

Вы организуете свой код в двух файлах:

  • guest.dart: Определите класс Guest, который представляет человека, посещающего мероприятие. Некоторые гости предоставляют полные данные, в то время как другие указывают только основные. Ваш класс должен содержать:
    • Не допускающую null строку String name — у каждого гостя должно быть имя
    • Допускающую null строку String? email — не все предоставляют адрес электронной почты
    • Допускающую null строку String? dietaryPreference — некоторые гости не указывают диетические предпочтения
    • Конструктор, который принимает name как обязательный параметр
    • Метод getDisplayEmail(), который возвращает email, если он доступен, или 'No email provided', используя оператор ??
    • Метод assignDefaultDiet(), который устанавливает dietaryPreference в значение 'Standard' только в том случае, если оно в данный момент равно null, используя оператор ??=
    • Метод getEmailDomain(), который возвращает длину email, используя ?., или null, если email отсутствует
    • Метод printBadge(), который выводит информацию для бейджа гостя
  • main.dart: Импортируйте ваш класс гостя и зарегистрируйте трех гостей с разным уровнем информации:
    • Создайте гостя по имени 'Alice', установите её email в 'alice@company.com', а диетическое предпочтение — в 'Vegetarian'
    • Создайте гостя по имени 'Bob', установите только его email в 'bob@email.org' (оставьте диетическое предпочтение равным null)
    • Создайте гостя по имени 'Charlie' (оставьте и email, и диетическое предпочтение равными null)
    • Вызовите assignDefaultDiet() для всех трех гостей
    • Для каждого гостя по порядку вызовите printBadge(), затем выведите Email length: [result], используя getEmailDomain()

Метод printBadge() должен выводить данные в следующем формате:

=== Guest Badge ===
Name: [name]
Email: [getDisplayEmail()]
Diet: [dietaryPreference or "Not specified"]

Обратите внимание, что диетическое предпочтение Алисы остается 'Vegetarian', потому что ??= присваивает значение только тогда, когда оно равно null, в то время как Бобу и Чарли назначается диета по умолчанию 'Standard'.

Ожидаемый вывод:

=== Guest Badge ===
Name: Alice
Email: alice@company.com
Diet: Vegetarian
Email length: 17
=== Guest Badge ===
Name: Bob
Email: bob@email.org
Diet: Standard
Email length: 13
=== Guest Badge ===
Name: Charlie
Email: No email provided
Diet: Standard
Email length: null

Шпаргалка

Dart предоставляет операторы с учетом null (null-aware operators) для более лаконичной работы с nullable-значениями.

Оператор объединения с null (null-coalescing operator) ?? возвращает левое значение, если оно не равно null, в противном случае возвращает правое значение:

String? nickname;
String displayName = nickname ?? 'Guest';
print(displayName);  // Guest

nickname = 'Alex';
displayName = nickname ?? 'Guest';
print(displayName);  // Alex

Оператор присваивания с учетом null (null-aware assignment operator) ??= присваивает значение только в том случае, если переменная в данный момент равна null:

String? username;
username ??= 'Anonymous';
print(username);  // Anonymous

username ??= 'NewName';
print(username);  // Still Anonymous (wasn't null)

Вы можете объединять в цепочку оператор доступа с учетом null ?. для вложенных свойств:

String? city = user?.address?.city;  // Безопасно, даже если user или address равны null

Эти операторы можно комбинировать друг с другом:

String greeting = user?.name ?? 'Stranger';
// Если user равен null ИЛИ user.name равен null, использовать 'Stranger'

Попробуйте сами

import 'guest.dart';

void main() {
  // TODO: Создайте гостя по имени 'Alice'
  // Установите её email на 'alice@company.com'
  // Установите её диетические предпочтения на 'Vegetarian'

  // TODO: Создайте гостя по имени 'Bob'
  // Установите только его email на 'bob@email.org'
  // Оставьте диетические предпочтения как null

  // TODO: Создайте гостя по имени 'Charlie'
  // Оставьте и email, и диетические предпочтения как null

  // TODO: Вызовите assignDefaultDiet() для всех трех гостей

  // TODO: Для каждого гостя по порядку (Alice, Bob, Charlie):
  // - Вызовите printBadge()
  // - Выведите 'Email length: [result]', используя getEmailDomain()
}
quiz iconПроверьте себя

В этом уроке есть небольшой тест. Начните урок, чтобы ответить на вопросы и сохранить прогресс.

Все уроки раздела Объектно-ориентированное программирование