Перейти к основному содержимому

Обработка значения null

Разработчику Аналитику Тестировщику
Архитектору Инженеру


Null

Что такое null?

Null (произносится как "налл") - это специальное значение, которое означает полное отсутствие данных, пустоту или то, что переменная ни на что не указывает.

Учтите:

  • есть 0 - это число;
  • есть "" - это пустая строка, пустой текст;
  • а есть Null, когда буквально ничего нет.

Что такое отсутствие значения?

Отсутствие значения — это фундаментальная концепция в программировании, отражающая состояние, когда данные ожидаются, но в текущий момент недоступны. Это состояние не эквивалентно нулю, пустой строке или ложному значению. Отсутствие значения означает: "место для данных зарезервировано, но содержимое отсутствует".

В реальном мире подобные ситуации встречаются постоянно:

  • Поле "дата увольнения" у действующего сотрудника
  • Опциональный параметр в конфигурации приложения
  • Результат поиска, не нашедший совпадений
  • Ссылка на объект, который ещё не создан

Программные языки формализуют это понятие через специальные значения, позволяющие явно выражать отсутствие данных в типизированной системе.

В программировании, для логически пустого значения, нельзя ставить прочерк ("-"), символы, или даже оставлять пустые кавычки. Значит, есть какое-то обозначение отсутствие значения, не так ли?


Null, Undefined, Nothing, None

В реальности мы часто сталкиваемся с отсутствием чего-либо. Но это - тоже информация - факт отсутствия. То есть, если на стуле никто не сидит, то это некое состояние, которое может быть ожидаемым, временным, аномальным или даже критичным. В программировании эту идею формализует понятие null — обозначение отсутствия значения.

null — это явное указание на отсутствие значения. Это специальное значение, означающее: "здесь должно быть что-то, но сейчас — пусто". Не объект, не число, не строка — это отдельное состояние. Можно явно его присвоить - программист говорит: "я знаю, что здесь пока нет значения".

Пример:

let user = null; // известно, что пользователь не выбран

Чтобы не путать с различными значениями, которые логически - ничего, давайте сделаем таблицу.

ЗначениеЧто на самом деле означает
null"Нет значения"
0"Число ноль"
"""Пустая строка"
false"Ложное значение"
undefined"Не определено" (JS)

Возраст null → неизвестен, а возраст 0 → новорождённый. Это разные смыслы, и их нельзя путать.

А что такое undefined? Вы наверняка слышали о "неопределённости".

undefined — это состояние "ещё не определено". Оно возникает, когда переменная объявлена, но не инициализирована, свойство объекта не существует, функция ничегоне возвращает, или параметр не передан.

Поэтому используйте null, когда намеренно хотите сказать "нет значения", а в JS сравнивайте с ===, чтобы избежать путаницы.

А теперь немного о страшном. В 2009 году Тони Хоар, создатель null в языке ALGOL, назвал это "миллиард-долларовой ошибкой". Почему null так опасен? NullPointerException (NPE) — одна из самых частых ошибок в Java, C#, JavaScript.

null не имеет методов, неявно проникает в логику программы, и если где-то логика должна, к примеру, получать объект, передавать его дальше, использовать его свойства или методы, но вместо объекта ничего не придёт - то будет та самая ошибка NPE. Поэтому нужно всегда выполнять проверку на null - это просто if (что-то == null) то, к примеру, return. Или наоборот, оборачивать нужную логику в if (что-то !== null).

Логически - "делай, только если данные есть". Искусство проверки на null в разных языках и проектах отличается, кто-то выделяет отдельные классы для проверок, кто-то использует nullable-типы (которые могут быть null).

Проверки на null — часть общей темы входных данных и валидации: Проверка и валидация.


Ключевые слова отсутствия значения

ЯзыкКлючевое словоТип значенияОсобенности
JavaScript / TypeScriptnullОтдельный примитивный типЯвное отсутствие значения
JavaScriptundefinedОтдельный примитивный типНеинициализированная переменная или отсутствующее свойство
PythonNoneСинглтон класса NoneTypeЕдинственное значение отсутствия
JavanullЛитерал без типаПрименим только к ссылочным типам
C#nullЛитерал без типаПрименим к ссылочным типам и nullable-типам
PHPnullСпециальный тип NULLЕдинственное значение типа
SwiftnilЗначение опционального типаТребует явного объявления опциональности
KotlinnullЗначение nullable-типаТребует суффикса ? в объявлении типа
RubynilЭкземпляр класса NilClassЕдинственное значение отсутствия
GonilНулевое значение для указателей, слайсов, мапПрименимо к составным типам
SQLNULLОтсутствие данных в ячейкеСпециальная семантика в запросах

Примеры использования отсутствия значения

JavaScript

// Явное указание отсутствия пользователя
let currentUser = null;

// Неинициализированная переменная
let pendingRequest;
console.log(pendingRequest); // undefined

// Отсутствующее свойство объекта
const profile = { name: "Алексей" };
console.log(profile.age); // undefined

В этом примере:

  • null — программист сознательно указал отсутствие текущего пользователя
  • undefined — переменная объявлена, но не получила значения
  • undefined — свойство age не существует в объекте profile

Python

# Отсутствие результата поиска
def find_user_by_id(user_id):
if user_id in database:
return database[user_id]
return None

user = find_user_by_id(999)
if user is None:
print("Пользователь не найден")

В этом примере:

  • None возвращается как сигнал об отсутствии результата
  • Проверка выполняется оператором is вместо == для корректного сравнения синглтона

Java

public class UserService {
private User currentUser = null;

public User getCurrentUser() {
return currentUser;
}

public void logout() {
currentUser = null;
}
}

В этом примере:

  • null присваивается ссылочной переменной currentUser
  • Метод logout() явно обнуляет ссылку на пользователя
  • Примитивные типы (int, boolean) не могут принимать значение null

C#

string optionalComment = null;
int? nullableAge = null; // Nullable<int>

if (optionalComment == null) {
optionalComment = "Комментарий отсутствует";
}

В этом примере:

  • Строковая переменная может содержать null как допустимое состояние
  • int? — сокращённая запись для Nullable<int>, позволяющая хранить отсутствие числового значения
  • Оператор ?? предоставляет значение по умолчанию при отсутствии данных

PHP

<?php
$middleName = null; // Отчество не указано

function getUserRole($userId) {
if (!isset($users[$userId])) {
return null; // Пользователь не найден
}
return $users[$userId]['role'];
}
?>

В этом примере:

  • null используется для опциональных полей данных
  • Функция возвращает null при отсутствии запрошенного пользователя
  • Проверка выполняется функцией is_null() или оператором ===

Проверки на отсутствие значения

Корректная обработка отсутствия значения предотвращает критические ошибки выполнения. Каждый язык предоставляет специфические механизмы проверки.


JavaScript

Код ITЗагрузка примера кода…

Оператор ?? возвращает правый операнд только при null или undefined, в отличие от ||, который срабатывает на любые ложные значения (0, "", false).


Python

# Корректная проверка через оператор is
if user is None:
create_default_user()

# Антипаттерн — неправильная проверка
if user == None: # Работает, но не рекомендуется
pass

# Использование or для значения по умолчанию
name = provided_name or "Аноним"

Проверка через is предпочтительнее, так как None является синглтоном, и сравнение по идентичности быстрее и надёжнее.


Java

Код ITЗагрузка примера кода…

Класс Optional предоставляет функциональный подход к работе с отсутствием значения, исключая необходимость явных проверок null.


C#

Код ITЗагрузка примера кода…

Система nullable reference types в современном C# позволяет выявлять потенциальные ошибки на этапе компиляции.


PHP

Код ITЗагрузка примера кода…

Оператор ?? в PHP работает аналогично JavaScript, возвращая правый операнд только при null.


Ошибки, связанные с отсутствием значения

Некорректная обработка отсутствия значения приводит к ошибкам времени выполнения. Каждый язык имеет свои специфические исключения.


Java — NullPointerException

User user = null;
String name = user.getName(); // NullPointerException здесь

Исключение возникает при попытке вызвать метод или обратиться к полю через null-ссылку. Это одна из самых распространённых ошибок в Java-приложениях.


C# — NullReferenceException

string text = null;
int length = text.Length; // NullReferenceException здесь

Аналог Java NullPointerException, возникает при разыменовании null-ссылки для доступа к членам объекта.


JavaScript — TypeError

const user = null;
console.log(user.name); // TypeError: Cannot read properties of null

JavaScript генерирует TypeError при попытке доступа к свойству или методу null или undefined.


Python — AttributeError

user = None
name = user.name # AttributeError: 'NoneType' object has no attribute 'name'

Python вызывает AttributeError при обращении к атрибуту объекта None.


PHP — TypeError или предупреждение

<?php
$user = null;
echo $user->name; // Fatal error: Uncaught Error: Call to a member function on null
?>

В современных версиях PHP вызов метода на null приводит к фатальной ошибке.


Nullable типы и современные подходы

Современные языки программирования развивают системы типов для безопасной работы с отсутствием значения на этапе компиляции.


Kotlin — Встроенная поддержка nullable типов

Код ITЗагрузка примера кода…

Kotlin разделяет типы на nullable (String?) и non-nullable (String) на уровне системы типов, что исключает большинство ошибок времени выполнения.


Swift — Опциональные типы

var name: String? = "Тимур"
name = nil // Разрешено

// Принудительное извлечение (опасно)
let forced = name!

// Опциональное связывание
if let unwrapped = name {
print(unwrapped.count)
}

// Оператор нулевого слияния
let displayName = name ?? "Гость"

Опциональные типы в Swift требуют явной обработки отсутствия значения перед использованием данных.


C# — Nullable reference types

#nullable enable
string message = null; // Предупреждение компилятора
string? nullableMessage = null; // Корректно

void Process(string input) { // input не может быть null
Console.WriteLine(input.Length);
}

Process(null); // Предупреждение компилятора
#nullable disable

Эта функция (доступна с C# 8.0) добавляет статический анализ для выявления потенциальных null-значений до выполнения программы.


TypeScript — Strict null checks

// tsconfig.json
{
"compilerOptions": {
"strictNullChecks": true
}
}

let value: string = "текст";
value = null; // Ошибка: Type 'null' is not assignable to type 'string'

let nullableValue: string | null = "текст";
nullableValue = null; // Разрешено

TypeScript с включённой опцией strictNullChecks требует явного указания null в типе для допустимости отсутствия значения.


Rust — Перечисление Option

Код ITЗагрузка примера кода…

Rust не имеет значения null. Вместо этого используется перечисление Option, которое явно выражает возможность отсутствия значения через типовую систему.