Go vs Rust — сравнение
| Go | Google, 2009; GC, горутины, простота |
|---|---|
| Rust | Mozilla, 2010 (1.0 — 2015); владение, без GC, безопасность памяти |
| Общее | компиляция в машинный код, статическая типизация, единый тулчейн |
| Go силён в | сетевых сервисах, облачной инфраструктуре, CLI |
| Rust силён в | системном ПО, производительности, встраиваемых системах, WebAssembly |
Go и Rust — два компилируемых языка со статической типизацией, которые часто сравнивают как современные альтернативы C, C++ и Java для серверного и системного программирования. Оба появились в 2009–2010 годах, оба компилируются в машинный код и поставляются с единым набором инструментов. Но их философии противоположны: Go оптимизирован под простоту и скорость разработки командами, Rust — под контроль, производительность и гарантии корректности на этапе компиляции.[1][2]
Происхождение
Go создали в Google Роберт Гриземер, Роб Пайк и Кен Томпсон (анонс в 2009, версия 1.0 в 2012). Цель — язык для больших кодовых баз и многоядерных серверов, быстро компилирующийся и легко читаемый новыми сотрудниками. Rust начал как личный проект Грейдона Хоара в Mozilla (2006), был официально поддержан в 2009–2010, версия 1.0 вышла в 2015 году. Цель — безопасная замена C++ для браузерного движка, без сборщика мусора и без ошибок памяти. С 2021 года Rust развивает независимый Rust Foundation.
Ключевые различия
| Go | Rust | |
|---|---|---|
| Управление памятью | сборщик мусора | владение и заимствование, без GC |
| Безопасность памяти | да (кроме гонок данных) | да, включая гонки данных; исключения — unsafe |
| Конкурентность | горутины и каналы в рантайме | потоки, async/await с внешним рантаймом |
| Обработка ошибок | значения error, if err != nil |
тип Result<T, E> и оператор ? |
| Обобщения | дженерики с 1.18, ограниченные | трейты и дженерики, мономорфизация |
| Метапрограммирование | генерация кода | макросы |
| Null | nil |
нет; вместо него Option<T> |
| Скорость компиляции | очень быстрая | медленная |
| Порог входа | низкий, язык осваивается за недели | высокий, «борьба с borrow checker» |
| Размер языка | ~25 ключевых слов, намеренно мал | большой, выразительный |
Производительность
Оба языка намного быстрее интерпретируемых. Rust обычно быстрее Go и сопоставим с C/C++: отсутствие GC, абстракции нулевой стоимости, агрессивные оптимизации LLVM, контроль над размещением данных в памяти. В синтетических тестах вроде Benchmarks Game Rust часто оказывается в 1,5–3 раза быстрее Go и потребляет меньше памяти.[7]
Для типичного сетевого сервиса разница часто несущественна: узкое место — база данных и сеть. Но заметна разница в предсказуемости задержек. Сборщик мусора Go конкурентный и делает паузы субмиллисекундными,[5] однако под большой нагрузкой с огромной кучей GC даёт периодические всплески задержки и расход процессора. Известный пример — Discord переписал сервис состояний прочтения с Go на Rust, избавившись от пиков задержки каждые две минуты.[4] Подробнее о компромиссах — в статье Сборка мусора vs ручное управление памятью.
Безопасность
Оба языка устраняют целый класс уязвимостей C/C++ — переполнения буфера, использование после освобождения. Rust идёт дальше: компилятор гарантирует отсутствие гонок данных и неинициализированной памяти. Google сообщал, что по мере роста доли кода на Rust и других безопасных языках в Android доля уязвимостей, связанных с памятью, упала с 76 % в 2019 году до 35 % в 2022-м.[6] В Go гонки данных возможны, их находит детектор -race (см. Состояние гонки и блокировки).
Продуктивность и сопровождение
Go выигрывает в скорости разработки: короткий цикл «правка — сборка — запуск», одна идиоматическая манера писать код (gofmt), богатая стандартная библиотека, простой код легко читать в ревью. Минус — многословность (if err != nil), меньше выразительных средств для моделирования предметной области.
Rust требует больше времени на изучение и написание, зато компилятор ловит больше ошибок до запуска: «если скомпилировалось — скорее всего работает». Система типов позволяет выразить инварианты (перечисления с данными, исчерпывающий match, типы-состояния), а Clippy подсказывает идиомы (см. Clippy и rustfmt). В опросах Stack Overflow Rust много лет подряд — самый «любимый» (admired) язык.[3]
Экосистема и применения
Go — язык облачной инфраструктуры: на нём написаны Docker, Kubernetes, Terraform, Prometheus, etcd, Caddy, Hugo, большинство CLI-утилит экосистемы CNCF. Типичные применения — микросервисы, API, прокси, DevOps-инструменты.
Rust используется там, где важны производительность и надёжность: части ядра Linux и Windows, Android, Firefox, сетевые прокси (Cloudflare Pingora), базы данных и движки хранения, WebAssembly, встраиваемые системы. Rust популярен и как «ускоритель» для экосистемы Python: uv, Ruff, Polars, Pydantic-core написаны на нём.
Как выбирать
- Go, если нужен сетевой сервис или инструмент, команда большая или меняется, важны скорость разработки и простота сопровождения, допустим GC.
- Rust, если критичны задержки и потребление памяти, нужен контроль над ресурсами, код работает близко к железу, в браузере через WebAssembly, встраивается в другие языки или его безопасность особенно важна.
- Оба языка хорошо сосуществуют: нередко сервисы пишут на Go, а «горячие» компоненты — на Rust.