Что такое Never
В языке программирования Dart тип Never представляет собой специальный тип, который указывает, что функция или выражение никогда не завершится успешно и никогда не вернёт управление. Это означает, что код либо завершает выполнение с ошибкой, либо зацикливается бесконечно, либо завершает выполнение программы.
📌 Основные характеристики типа Never
-
Never — это подтип всех типов (bottom type):
-
Это означает, что значение типа Never можно подставить вместо любого другого типа, потому что оно никогда не существует.
-
Используется, когда выполнение кода никогда не дойдёт до этой точки.
-
-
Never — это тип, который нельзя инстанцировать:
-
Нельзя создать переменную типа Never, потому что не существует значения этого типа.
-
Его можно использовать только в сигнатурах функций или в типах, чтобы описать поведение, при котором управление не возвращается.
-
🧠 Когда и зачем используется Never
1. Функции, которые выбрасывают исключения
Never throwError(String message) {
throw Exception(message);
}
-
Функция возвращает Never, потому что она никогда не завершится успешно — она сразу бросает исключение.
-
Это помогает компилятору и анализатору Dart понять, что после вызова этой функции выполнение не продолжится.
2. Функции с бесконечным циклом
Never infiniteLoop() {
while (true) {
// бесконечный цикл
}
}
-
Такая функция никогда не возвращает, и тип Never делает это явным.
-
Полезно для описания функций, которые работают в фоновом режиме или блокируют поток выполнения навсегда.
3. Оператор switch с исчерпывающим перечислением (exhaustive switch)
Если вы используете sealed class или enum, Dart может потребовать указания всех возможных вариантов. Если один из case завершает выполнение с исключением, можно указать Never, чтобы Dart понял, что это корректно.
enum ShapeType { circle, square }
String shapeName(ShapeType type) {
switch (type) {
case ShapeType.circle:
return "Circle";
case ShapeType.square:
throw UnimplementedError("Square not yet supported");
}
}
В таком случае throw возвращает Never, и Dart понимает, что ветка не завершится успешно, даже если значение square не возвращает строку.
4. Типизация с ! (non-null assertion operator)
Тип Never также играет роль при использовании !, например:
String? maybeStr;
print(maybeStr!); // Если maybeStr == null, будет выброшено исключение
В случае ошибки maybeStr! фактически приводит к Never, потому что программа завершится с исключением, и никакое значение не будет возвращено.
🔬 Never vs Null vs void
Тип | Назначение | Может быть возвращён? |
---|---|---|
void | Означает отсутствие возвращаемого значения (но функция завершается) | ✅ Да |
--- | --- | --- |
Null | Единственный допустимый тип, содержащий null | ✅ Да |
--- | --- | --- |
Never | Означает, что функция не завершится нормально и не вернёт ничего | ❌ Нет |
--- | --- | --- |
📚 Примеры использования Never в реальных проектах
-
В assert или throw: явно указывая, что после этого кода выполнение не продолжится.
-
При проверке ошибок: если функция должна прервать выполнение при неразрешимом состоянии.
-
В функциональных паттернах (например, Result / Either), где неуспешные ветви можно завершить через Never.
Пример в стиле функционального программирования:
Either<Error, Data> fetchData();
void processData() {
final result = fetchData();
result.fold(
(error) => throwError(error.message), // Возвращает Never
(data) => print(data),
);
}
🧩 Роль Never в системе типов Dart
Dart — это язык с строгой типизацией, и Never играет важную роль:
-
Повышает безопасность типов.
-
Позволяет компилятору анализировать контроль потока (control flow analysis).
-
Улучшает анализатор кода: он может предупреждать об unreachable code, dead code и забытых return.
Таким образом, Never — это фундаментальный элемент системы типов Dart, предназначенный для описания ситуаций, в которых выполнение кода гарантированно не завершится успешно и не вернёт управление.