Переменные
This content is not available in your language yet.
В Python переменная — это имя, привязанное к объекту, и её можно в любой момент перепривязать к чему угодно. В Mojo переменная — это участок памяти известного размера с известным типом. Отсюда все отличия ниже.
Объявление
Заголовок раздела «Объявление»Переменная объявляется словом var при первом присваивании:
var count: Int = 0 # с явным типомvar total = 0.0 # тип выведен из значения — здесь Float64var name = "Аня" # StringДальше var не нужен — это уже не объявление, а изменение значения:
count = 5count += 1Тип фиксируется навсегда
Заголовок раздела «Тип фиксируется навсегда»Тип переменной определяется в момент объявления и больше не меняется:
x = 1x = "теперь строка" # нормальноvar x = 1x = "теперь строка" # ошибка компиляцииВ Python имя просто перевешивается на другой объект. В Mojo под x
отведено восемь байт под целое число — строка туда не поместится
ни физически, ни по смыслу.
error: cannot implicitly convert 'StringLiteral[...]' value to 'Int'
Вы присваиваете переменной значение другого типа.
Либо заведите новую переменную с другим именем, либо преобразуйте
значение явно: var text = String(x).
Объявить сейчас, присвоить позже
Заголовок раздела «Объявить сейчас, присвоить позже»Так можно — но пользоваться значением до присваивания компилятор не даст:
var limit: Int # объявлена, но пустаlimit = 100 # теперь в ней есть значениеerror: use of uninitialized value 'x'
Переменная объявлена, но значение в неё ещё не положили — а вы уже пытаетесь его прочитать.
Присвойте значение до первого использования. Компилятор отслеживает все ветви кода: если хотя бы по одной из них переменная остаётся пустой, будет ошибка.
Это важнее, чем кажется. В Python неинициализированная переменная —
это NameError во время выполнения, у пользователя. В Mojo такой код
просто не соберётся.
Область видимости — по блокам
Заголовок раздела «Область видимости — по блокам»Главное отличие от Python. Переменная живёт до конца блока, в котором объявлена, а не до конца функции:
if True: message = "привет"print(message) # работаетif True: var message = "привет"print(message) # ошибка: имя неизвестноБлок — это тело if, while, for, with и любой другой
конструкции с отступом. Как в C++, Rust или Java.
error: use of unknown declaration 'message'
Имя не существует в этой точке программы: либо опечатка, либо переменная объявлена во вложенном блоке и уже «умерла».
Объявите переменную до блока, если она нужна и после него.
Внутри вложенного блока имя можно затенить (shadow) — это будет отдельная переменная, а внешняя останется нетронутой.
Всё вместе
Заголовок раздела «Всё вместе»def main(): var counter = 0
# Переменная, объявленная внутри блока, живёт только в этом блоке if counter == 0: var message = "счётчик пуст" print(message)
# Здесь `message` уже не существует — попытка обратиться к нему # не скомпилируется
# Имя можно затенить во вложенном блоке: это разные переменные var name = "внешняя" while counter < 1: var name = "внутренняя" print("внутри блока:", name) counter += 1 print("снаружи блока:", name)
# Объявить сейчас, значение присвоить позже — можно var limit: Int if counter > 0: limit = 100 else: limit = 0 print("предел:", limit)счётчик пуст внутри блока: внутренняя снаружи блока: внешняя предел: 100
Все переменные изменяемы
Заголовок раздела «Все переменные изменяемы»В ранних версиях Mojo была пара let и var — для неизменяемых
и изменяемых переменных. В 1.0 let удалён: любую переменную можно
изменить.
Означает ли это, что от неизменяемости отказались? Нет — её перенесли туда, где она действительно нужна: в передачу аргументов. Функция получает значение только для чтения, если явно не сказано иначе. Подробно — в главе Конвенции передачи аргументов.
Константы времени компиляции
Заголовок раздела «Константы времени компиляции»Если значение известно заранее и меняться не должно, объявите его через
comptime — компилятор вычислит его на этапе сборки и подставит в код:
comptime MAX_USERS = 100
def main(): comptime BUFFER = 4096 print(MAX_USERS, BUFFER)100 4096
Такие значения можно использовать там, где обычная переменная не подойдёт — например, задавать размер массива или ширину SIMD-вектора. Об этом целый раздел Метапрограммирование.
Правила как в Python: буквы, цифры, подчёркивания, начинать с цифры нельзя. Кириллица в именах технически возможна, но не используйте её — код читают и правят разные люди, а раскладку переключать неудобно.
Принятый стиль в Mojo совпадает с питоновским: snake_case для переменных
и функций, CamelCase для типов, UPPER_CASE для констант.
🎯 Проверь себя
Почему `var message` внутри `if` не виден после блока?
В Mojo область видимости переменной ограничена блоком, где она объявлена. Это позволяет компилятору точно знать, когда значение больше не нужно, и вовремя освободить память. В Python область видимости — вся функция.
Можно ли объявить переменную без значения?
Да: var limit: Int. Но прочитать её до первого присваивания нельзя —
компилятор проверяет все ветви кода и выдаст ошибку
use of uninitialized value.
Куда делось ключевое слово `let` из старых примеров?
Удалено в Mojo 1.0. Все переменные изменяемы, а неизменяемость выражается конвенцией передачи аргументов: функция по умолчанию получает значение только для чтения.
Что дальше
Заголовок раздела «Что дальше»Мы всё время говорили «тип выведен из значения». Пора разобраться,
какие вообще бывают типы и почему Int — это не то же
самое, что Int64.
Тексты курса — CC BY-NC-SA 4.0, код примеров — Apache 2.0