Programming

Типы данных и типизация

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

Что такое тип данных

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

Типизация — набор правил языка о том, когда типы проверяются (при компиляции или во время выполнения) и насколько строго. Это свойство языка, а не программиста.

Базовые типы

Тип Что хранит Примеры значений
boolean (bool) Истина или ложь true, false
integer (int) Целое число -3, 0, 42
float / double Дробное число 3.14, -0.5
string (str) Текст "привет"
null / None Отсутствие значения null, None, nil
array / list Упорядоченный набор [1, 2, 3]
object / dict Пары ключ-значение {"id": 1}

Boolean — что это

Boolean (булев, логический тип) — тип ровно с двумя значениями: истина и ложь. Назван в честь Джорджа Буля, автора алгебры логики XIX века. Это результат любого сравнения (a > b) и вход любого условия (if).

Формально одного бита хватило бы, но на практике bool занимает байт и больше — процессору неудобно адресовать отдельные биты.

Практическая тонкость — приведение к bool. Многие языки считают «ложными» не только false:

bool(0), bool(""), bool([]), bool(None)   # всё False
bool("0"), bool("False"), bool([0])       # всё True — строка непуста, список непуст

Отсюда классическая ошибка: if value: вместо if value is not None:. Для value = 0 первый вариант не сработает, хотя значение задано.

Статическая и динамическая типизация

Статическая Динамическая
Когда проверка При компиляции Во время выполнения
Тип привязан к Переменной Значению
Ошибка типа находится До запуска В проде, в 3 часа ночи
Скорость разработки Ниже на старте Выше на старте
Скорость выполнения Обычно выше Обычно ниже
Языки Java, C#, Go, Rust, TypeScript Python, JavaScript, PHP, Ruby

Динамическая типизация — это когда тип принадлежит значению, а не переменной, и проверяется в момент операции:

x = 42        # сейчас int
x = "сорок"   # теперь str — язык не возражает
x + 1         # TypeError, но только когда до этой строки дойдёт выполнение

В Java такое не скомпилируется вовсе: int x = 42; x = "сорок"; — ошибка на этапе сборки.

Строгая и слабая типизация

Ось другая, и её постоянно путают со статикой. Строгая типизация — язык не приводит типы молча; слабая — приводит:

"1" + 1    # Python: TypeError — строгая типизация
"1" + 1    // JavaScript: "11" — число стало строкой
"3" * 2    // 6 — а тут наоборот, строка стала числом

Обе оси независимы: Python — динамический и строгий, JavaScript — динамический и слабый, Java — статический и строгий, C — статический и относительно слабый.

mypy и аннотации типов в Python

mypy — статический анализатор типов для Python. Он не меняет поведение программы (интерпретатор аннотации игнорирует) — он читает код и находит несоответствия до запуска, добавляя Python преимущество статической проверки без потери динамики.

def get_user(user_id: int) -> dict[str, str] | None:
    ...

get_user("42")     # mypy: Argument 1 has incompatible type "str"; expected "int"
pip install mypy
mypy app/ --strict        # строгий режим: требует аннотаций везде

Аналоги: pyright (быстрее, живёт в VS Code), TypeScript для Node.js. Практическая ценность растёт с размером кодовой базы: на скрипте в 50 строк mypy не нужен, на проекте в 50 тысяч строк он ловит целый класс ошибок, до которых иначе доберутся только тесты или пользователи.

Связанные термины

  • Python — динамическая строгая типизация плюс аннотации
  • Java — статическая строгая типизация
  • Конкатенация — где разница строгой и слабой типизации виднее всего
  • SQL — типы колонок в базе и их отличия от типов языка
  • IDE — подсказывает типы и подсвечивает несоответствия на лету

Готовы запустить GPU-задачу?

Запустить GPU-сервер