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

Первая программа

Если окружение уже настроено, напишем первую осмысленную программу и разберём её построчно. Она короткая, но в ней уже видны три главных отличия Mojo от Python.

temperature.mojo
def average(values: List[Float64]) -> Float64:
var total = 0.0
for value in values:
total += value
return total / Float64(len(values))
def main():
var measurements: List[Float64] = [21.5, 23.0, 19.8, 24.2]
var mean = average(measurements)
print("Средняя температура:", mean)

Запустим:

Окно терминала
uv run mojo temperature.mojo
Результат

Средняя температура: 22.125

def main():
print("Привет!")

В Python код можно писать прямо на верхнем уровне файла, и он выполнится сверху вниз. В Mojo так нельзя: каждая программа обязана содержать функцию main() — именно с неё начинается выполнение.

🐍 Python
# Работает: код на верхнем уровне
print("Привет!")
🔥 Mojo
# Обязательно внутри main()
def main():
print("Привет!")

В коротких примерах этого курса def main() иногда опускается ради краткости — как и в официальном мануале. Но чтобы запустить такой фрагмент у себя, оберните его в main().

def average(values: List[Float64]) -> Float64:

В Python аннотации типов — подсказка для человека и линтера; интерпретатору на них всё равно. В Mojo тип — это указание компилятору, как разместить значение в памяти и какие машинные инструкции сгенерировать. Без типа компилятор не может собрать эффективный код, поэтому типы аргументов и возвращаемого значения обязательны.

Именно отсюда берётся скорость: Float64 — это не объект с заголовком, счётчиком ссылок и таблицей методов, как float в CPython, а восемь байт в регистре процессора.

🐍 Python
def average(values):
return sum(values) / len(values)
🔥 Mojo
def average(values: List[Float64]) -> Float64:
var total = 0.0
for value in values:
total += value
return total / Float64(len(values))

Аннотация -> Float64 — это не документация, а контракт: компилятор проверит его на этапе сборки, а не в момент падения программы у пользователя.

var total = 0.0

Первое присваивание объявляет переменную, и перед ним пишется var:

var count: Int = 0 # с явным типом
var count = 0 # тип выведен из значения
count = 1 # это уже не объявление, а изменение значения

Присваивание без var при первом упоминании пока работает, но компилятор на него ругается:

warning: implicit declaration of 'count' is deprecated;
add 'var' before the assignment target

Сегодня это предупреждение, в следующих версиях станет ошибкой — так что привыкайте сразу писать var.

mojo temperature.mojo компилирует и сразу запускает программу — удобно при разработке. Но Mojo — компилируемый язык, и результат можно получить в виде обычного исполняемого файла:

Окно терминала
uv run mojo build temperature.mojo
./temperature
Результат

Средняя температура: 22.125

Получившийся бинарник не требует ни интерпретатора, ни виртуального окружения — его можно просто скопировать на другую машину с той же архитектурой и запустить. Для Python-разработчика это, пожалуй, самое непривычное ощущение от языка.

error: expected type in function signature
Что это значит

У аргумента функции не указан тип. Компилятор дошёл до имени аргумента, ожидал двоеточие и тип, но не нашёл их.

Как исправить

Допишите тип: def average(values: List[Float64]) -> Float64:. Привычка из Python писать def average(values) здесь не работает.

error: 'fn' is deprecated, use 'def' instead
Что это значит

Вы используете ключевое слово fn, оставшееся от старых версий языка.

Как исправить

Замените fn на def. Семантика при этом не меняется: в Mojo 1.0 def ведёт себя ровно так, как раньше вёл себя fn — в частности, функция не считается способной бросать исключения, пока вы явно не напишете raises.

🎯 Проверь себя

Почему в Mojo нельзя писать код на верхнем уровне файла, как в Python?

Потому что Mojo — компилируемый язык, а не интерпретируемый: у программы должна быть определённая точка входа, с которой начинается выполнение собранного бинарника. Эту роль играет функция main().

Чем аннотация типа в Mojo отличается от аннотации типа в Python?

В Python аннотация ни на что не влияет во время выполнения — это подсказка для человека и инструментов. В Mojo тип определяет представление значения в памяти и генерируемый машинный код, поэтому он обязателен и проверяется компилятором.

В чём разница между `var x = 0` и `x = 0` внутри функции?

В области видимости. var x живёт до конца блока, в котором объявлен (например, внутри if), а x = 0 без var — до конца всей функции, как в Python.

Дальше разберём систему типов — почему Int в Mojo это не то же самое, что int в Python, и откуда берётся тип SIMD, которого в Python нет вовсе.

Примеры проверены на Mojo 1.0.0

Тексты курса — CC BY-NC-SA 4.0, код примеров — Apache 2.0