Типы данных и типизация
Тип данных задаёт множество допустимых значений и операций над ними, а типизация — правила языка о том, когда и насколько строго типы проверяются.
Что такое тип данных
Тип данных — характеристика значения, определяющая две вещи: какие значения допустимы и какие операции над ними имеют смысл. Число 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-сервер