Rust против C++, Go и Python
«Учить Rust, или Go, или остаться на Python?» — один из самых частых вопросов у тех, кто только узнал о Rust. Честный ответ: зависит от того, что ты хочешь создавать. Все языки на этой странице хорошие, ими пользуются миллионы людей. Просто каждый из них сделал свои компромиссы.
Представь языки как транспорт. Спорткар, фургон и велосипед — все «хорошие». Просто на велосипеде не перевозят мебель. Эта страница простыми словами объясняет компромиссы, чтобы ты мог выбрать подходящий инструмент для своей задачи. Мы постараемся быть честными, в том числе насчёт слабых мест Rust.
В чём Rust хорош
Заголовок раздела «В чём Rust хорош»Главное обещание Rust — скорость и безопасность одновременно:
- Быстрый, как C и C++. Rust компилируется в машинный код и не использует сборщик мусора, поэтому нет пауз на очистку памяти.
- Безопасная работа с памятью без сборщика мусора. Правила владения и заимствования проверяются при компиляции. Целые группы ошибок (использование освобождённой памяти, гонки данных между потоками) отвергаются ещё до запуска программы.
- Отличные инструменты из коробки. Один инструмент, Cargo, собирает код, скачивает библиотеки, запускает тесты и генерирует документацию. Форматтер (
rustfmt) и линтер (clippy) — официальные. - Полезные сообщения об ошибках. Компилятор часто прямо говорит, как исправить проблему.
И разработчикам он, похоже, нравится: в опросе разработчиков Stack Overflow 2025 года (на английском) Rust снова стал «самым любимым» языком — то есть большинство тех, кто на нём пишет, хотят продолжать.
Одна задача на четырёх языках
Заголовок раздела «Одна задача на четырёх языках»Начнём с простого: сложим чётные числа из списка. Вот так это выглядит на Rust:
fn main() { let numbers = vec![1, 2, 3, 4, 5, 6]; let sum: i32 = numbers.iter().filter(|n| *n % 2 == 0).sum(); println!("Сумма чётных чисел: {sum}");}Вывод:
Сумма чётных чисел: 12Та же программа на C++:
#include <iostream>#include <vector>
int main() { std::vector<int> numbers = {1, 2, 3, 4, 5, 6}; int sum = 0; for (int n : numbers) { if (n % 2 == 0) { sum += n; } } std::cout << "Сумма чётных чисел: " << sum << "\n";}На Go:
package main
import "fmt"
func main() { numbers := []int{1, 2, 3, 4, 5, 6} sum := 0 for _, n := range numbers { if n%2 == 0 { sum += n } } fmt.Println("Сумма чётных чисел:", sum)}И на Python:
numbers = [1, 2, 3, 4, 5, 6]total = sum(n for n in numbers if n % 2 == 0)print("Сумма чётных чисел:", total)Все четыре выводят одну и ту же строку. Python короче всех, Go и C++ используют обычный цикл, а Rust — цепочку итераторов с замыканием (в Rust тоже можно написать цикл for). В таких маленьких программах разница в основном в стиле. Настоящие различия проявляются в больших программах.
Rust против C++
Заголовок раздела «Rust против C++»C++ и Rust нацелены на одну и ту же область: быстрые программы с полным контролем над памятью — браузеры, игровые движки, базы данных и операционные системы. Главное различие в том, кто проверяет, что память используется правильно.
В C++ это делаешь ты. Вот классическая ошибка. Компилятор C++ примет этот код без единой жалобы, но push_back может перенести вектор в новую область памяти, и тогда first будет указывать на уже освобождённую память:
std::vector<int> v = {1, 2, 3};int& first = v[0];v.push_back(4); // может перенести память вектора...std::cout << first << "\n"; // ...и тогда здесь читается освобождённая памятьТа же ошибка в Rust не скомпилируется:
fn main() { let mut v = vec![1, 2, 3]; let first = &v[0]; v.push(4); println!("{first}");}error[E0502]: cannot borrow `v` as mutable because it is also borrowed as immutable --> src/main.rs:4:5 |3 | let first = &v[0]; | - immutable borrow occurs here4 | v.push(4); | ^^^^^^^^^ mutable borrow occurs here5 | println!("{first}"); | ----- immutable borrow later used hereКомпилятор говорит: нельзя заимствовать v как изменяемое, потому что оно уже заимствовано как неизменяемое, и это неизменяемое заимствование используется дальше.
На практике это очень важно. Команда Chromium сообщает, что около 70% их серьёзных уязвимостей — это проблемы безопасности памяти (на английском). Команда Android в Google уже несколько лет пишет новый код на Rust. В 2022 году они сообщили, что в коде Android на Rust не найдено ни одной уязвимости, связанной с памятью (на английском), а в 2025 году — что плотность уязвимостей памяти в нём более чем в 1000 раз ниже, чем в их коде на C и C++ (на английском). Ядро Linux (на английском) тоже поддерживает код на Rust.
Инструменты: у C++ много систем сборки и пакетных менеджеров, и команды часто тратят заметное время на настройку. У Rust есть один стандартный инструмент — Cargo, поэтому любой проект на Rust собирается одинаково.
Порог входа: оба языка сложные. C++ огромен, и многие его правила узнаёшь, совершая ошибки во время работы программы. Правила Rust строгие, но компилятор следит за ними и объясняет их, поэтому ты учишь их на этапе компиляции.
Где C++ всё ещё выигрывает: десятилетия существующего кода, библиотеки и опытные разработчики. Если твоя компания или твой игровой движок построены на C++, то C++ часто будет практичным выбором. Rust умеет вызывать код на C, а C++ — через интерфейсы в стиле C, но совмещать их требует усилий.
Rust против Go
Заголовок раздела «Rust против Go»Go и Rust часто сравнивают: оба современные, компилируемые и популярные для серверов и консольных утилит. Но их создавали с разными целями.
Сборка мусора против владения. Go использует сборщик мусора (на английском), который находит и освобождает неиспользуемую память во время работы программы. Поэтому код на Go проще писать: ты никогда не думаешь о том, кто владеет значением. Цена — немного лишней памяти и процессорного времени и короткие паузы. В Rust сборщика мусора нет. Память освобождается в известный момент — когда владелец выходит из области видимости. Это даёт более предсказуемую производительность, но придётся освоить владение и заимствование.
Многопоточность. Горутины и каналы Go знамениты своей простотой. Вот небольшой пример, который параллельно возводит в квадрат три числа и складывает результаты:
results := make(chan int)
for n := 1; n <= 3; n++ { go func() { results <- n * n }()}
total := 0for i := 0; i < 3; i++ { total += <-results}fmt.Println("итого:", total)Версия на Rust использует потоки и канал. Она чуть многословнее: для каждого потока нужно клонировать отправителя и использовать move:
use std::sync::mpsc;use std::thread;
fn main() { let (tx, rx) = mpsc::channel();
for n in 1..=3 { let tx = tx.clone(); thread::spawn(move || { tx.send(n * n).unwrap(); }); } drop(tx); // закрываем свою копию, чтобы цикл ниже мог завершиться
let total: i32 = rx.iter().sum(); println!("итого: {total}");}Вывод:
итого: 14Что ты получаешь за лишние строчки: Rust отказывается компилировать код, в котором два потока могут одновременно менять одни и те же данные (гонка данных, data race). В Go гонки данных возможны; для их поиска есть детектор гонок (на английском), который находит их во время работы программы. Подробнее — в уроке Многопоточность.
Время компиляции. Go создавали так, чтобы он компилировался быстро. В его FAQ сказано, что сборка большого исполняемого файла должна занимать не больше нескольких секунд (на английском). Rust компилируется медленнее, потому что компилятор гораздо больше проверяет и оптимизирует. На больших проектах это заметно.
Простота. Go намеренно маленький язык с небольшим набором возможностей, поэтому многие быстро начинают читать код на Go. В Rust возможностей больше (трейты, обобщения, времена жизни, макросы): они дают больше силы, но на их изучение уходит больше времени.
Rust против Python
Заголовок раздела «Rust против Python»Python и Rust очень разные, и их часто используют вместе, а не вместо друг друга.
Скорость. Python интерпретируемый, поэтому чистый код на Python, который много вычисляет, намного медленнее компилируемого. Именно поэтому популярные библиотеки для Python часто делают тяжёлую работу на C, C++ или Rust «под капотом».
Типизация. В Python типы проверяются во время работы программы. Эта функция работает с числом и падает со строкой, но узнаёшь ты об этом, только когда выполнится эта строка:
def add_tax(price): return price * 1.2
print(add_tax(10)) # 12.0print(add_tax("10")) # TypeError: can't multiply sequence by non-int of type 'float'В Python есть необязательные подсказки типов, но среда выполнения Python их не проверяет (на английском). В Rust каждый тип проверяется до запуска программы:
fn add_tax(price: f64) -> f64 { price * 1.2}
fn main() { println!("{}", add_tax(10.0)); println!("{}", add_tax("10"));}error[E0308]: mismatched types --> src/main.rs:7:28 |7 | println!("{}", add_tax("10")); | ------- ^^^^ expected `f64`, found `&str` | | | arguments to this function are incorrectКомпилятор говорит о несовпадении типов: ожидался f64, а передана строка &str.
Когда Python всё ещё лучше: быстрые скрипты, анализ данных, машинное обучение, ноутбуки, автоматизация и обучение новичков. Экосистема Python для data science огромна, и идею можно проверить за минуты. Если программа большую часть времени ждёт сеть или базу данных, скорость Python часто не важна.
Используем оба: проект PyO3 (на английском) позволяет писать модули для Python на Rust, так что можно оставить свой код на Python и перенести в Rust только медленную часть. Некоторые популярные инструменты для Python сами написаны на Rust; например, в опросе Stack Overflow отмечено, что пакетный менеджер uv для Python написан на Rust (на английском).
Сравнение бок о бок
Заголовок раздела «Сравнение бок о бок»Это общие тенденции, а не строгие правила. Хорошо написанная программа на любом из этих языков может быть «достаточно быстрой».
| Rust | C++ | Go | Python | |
|---|---|---|---|---|
| Скорость | Очень высокая, машинный код, без GC | Очень высокая, машинный код, без GC | Высокая, машинный код со сборщиком мусора | Ниже при тяжёлых вычислениях на чистом Python |
| Безопасность памяти | Проверяется при компиляции (вне unsafe) |
Ответственность программиста | GC; гонки данных всё ещё возможны | GC; безопасно, но ошибки типов всплывают во время работы |
| Порог входа | Поначалу крутой | Крутой, и язык очень большой | Пологий | Самый пологий |
| Время компиляции | Довольно долгое | Довольно долгое (зависит от проекта) | Очень быстрое | Компиляции нет |
| Экосистема | Моложе, растёт; Cargo встроен | Огромная и зрелая; много инструментов сборки | Сильная стандартная библиотека, отлично для серверов | Огромная, особенно для данных и ML |
| Типичные применения | CLI-утилиты, серверы, системный код, WebAssembly, встраиваемые системы | Игры, браузеры, высокопроизводительные и унаследованные системы | Веб-сервисы, облачные и DevOps-инструменты | Скрипты, data science, ML, автоматизация |
Когда выбирать Rust?
Заголовок раздела «Когда выбирать Rust?»Задай себе такие вопросы:
- Нужна максимальная скорость или малое потребление памяти, например игровой движок, база данных или код на маленьком устройстве? Rust (или C++) — сильный выбор.
- Ошибки будут дорогими? Код, критичный для безопасности, долго работающие серверы и код, от которого зависят многие люди, больше всего выигрывают от проверок Rust при компиляции.
- Делаешь консольную утилиту, которой хочешь поделиться? Rust выдаёт один быстрый исполняемый файл, без среды выполнения, которую нужно устанавливать. Go здесь тоже отлично подходит.
- Нужен веб-сервис побыстрее, а команда новичок во всех этих языках? С Go вы, скорее всего, доберётесь до цели быстрее. Rust тоже хорошо подходит (см. Проект: веб-API на Axum), но на обучение уйдёт больше времени.
- Это быстрый скрипт, анализ данных или эксперимент с ML? Бери Python. К Rust можно обратиться позже, через PyO3, если какая-то часть окажется слишком медленной.
- Есть большая существующая кодовая база на C++? Пока оставайся на C++ или добавляй Rust в новые, отдельные части, как это сделали в Android.
А если ты просто хочешь стать лучше как программист: Rust учит, как на самом деле устроена память, и это знание пригодится в любом другом языке.
Честные минусы Rust
Заголовок раздела «Честные минусы Rust»Rust не идеален. Вот с чем люди мучаются чаще всего:
- Порог входа реален. Первые недели с анализатором заимствований (borrow checker) могут раздражать. Приготовься какое-то время «бороться с компилятором». Как только владение уляжется в голове, станет намного легче.
- Время компиляции больше, чем у Go, особенно на больших проектах и в релизных сборках.
- Некоторые вещи выразить сложнее. Данные в виде графа с множеством связей между объектами или код, который активно разделяет изменяемое состояние, требуют инструментов вроде умных указателей и более тщательного планирования.
- Экосистема моложе. В некоторых областях (GUI-приложения, отдельные научные библиотеки) зрелых вариантов меньше, чем в C++ или Python.
- Им пользуется меньше людей (пока). В опросе Stack Overflow 2025 года (на английском) гораздо больше участников сказали, что используют Python (около 58%) или C++ (около 24%), чем Rust (около 15%). Значит, меньше опытных разработчиков на Rust, которых можно нанять, у которых можно спросить или поучиться на работе.
- Больше кода для простых вещей. Как показал пример с каналом, Rust часто просит явности там, где другие языки расслаблены.
- Rust даёт скорость уровня C++ с безопасностью памяти, которая проверяется при компиляции, и отличные встроенные инструменты.
- По сравнению с C++ Rust предотвращает целые классы ошибок памяти до запуска программы; у C++ гораздо больше существующего кода и библиотек.
- По сравнению с Go в Rust нет сборщика мусора, а гонки данных останавливаются при компиляции; Go проще и компилируется намного быстрее.
- По сравнению с Python Rust намного быстрее и проверяет типы до запуска; на Python быстрее писать, и он доминирует в data science. PyO3 позволяет их совмещать.
- Главная цена Rust — крутой порог входа, более медленная компиляция и более молодая экосистема.
Проверь себя
Заголовок раздела «Проверь себя»Проверь себя
1. Как Rust управляет памятью без сборщика мусора?
2. Какое из этих преимуществ Go перед Rust справедливо?
3. В программе на Python одна функция работает слишком медленно. Какой подход распространён?
4. Что происходит в примере C++ против Rust с кодом, который хранит &v[0], а потом добавляет элемент в v?
Результат: 0 / 4
Что почитать
Заголовок раздела «Что почитать»- Язык программирования Rust — Введение: для кого Rust, словами самой официальной книги (перевод на русский).
- Rust in Android: move fast and fix things — Google Security Blog (на английском): реальные данные большой команды, которая использует Rust вместе с C и C++.
- Stack Overflow Developer Survey 2025 — Admired and Desired (на английском): как разработчики относятся к Rust, Go, Python, C++ и другим языкам.
- Go FAQ — Why did you create a new language? (на английском): цели, с которыми создавали Go, — полезно, чтобы понять, где он особенно хорош.
- Руководство PyO3 (на английском): как писать расширения для Python на Rust.