TGViewer
dev notes dev notes @junsenior · 1.39K subscribers
Post #315 658
В рамках подготовки одного материала копаюсь в Rust и пытаюсь понять, как он работает и чем отличается от Go в плане работы с памятью.

Ниже решил поделиться одним примером, который без проблем компилируется в Go, и не компилируется в Rust.

Есть код:

func main() {
var r *int
{
x := 5
r = &x
}
fmt.Println(*r)
}

Этот код собирается и запускается без ошибок. Что тут происходит: мы объявляем локальный блок со своей областью видимости, где объявляем переменную x = 5, и затем копируем ссылку на нее в r.
Ниже, когда блок с объявлением и копированием завершился - мы разименовываем r и выводим значение:

➜ go run main.go
5


Давай теперь напишем тот же код на Rust:

fn main() {
let r;
{
let x = 5;
r = &x;
}
println!("{}", r);
}


Компилятор поведет себя примерно так:

➜ git:(master) ✗ cargo build
Compiling memory v0.1.0 (/Users/poltora.dev/rust/memory)
error[E0597]: `x` does not live long enough
--> src/main.rs:5:13
|
4 | let x = 5;
| - binding `x` declared here
5 | r = &x;
| ^^ borrowed value does not live long enough
6 | }
| - `x` dropped here while still borrowed
7 | println!("r: {}", r);
| - borrow later used here

For more information about this error, try `rustc --explain E0597`.
error: could not compile `memory` (bin "memory") due to 1 previous error


Ну во-первых, компилятор Rust - мое почтение 😎. Очень подробный анализ ошибок (но это неспроста, ниже объяснение - почему).
А во-вторых, почему мы получили ошибку?

Все дело в базовой концепции работы Go и Rust с памятью. В Go компилятор имеет фазу escape-анализа, которая проверяет код и помечает, на стек или на кучу должна упасть та или иная переменная. Когда компилятор видит, что переменная r принимает значение из локальной области видимости (x) - он перемещает ее на кучу - в общую память процесса, с которой могут работать все потоки.
Затем, в процессе работы программы, параллельно с Go вступает в игру Garbage Collector, который дает нам гарантию, что все такие переменные, даже если мы про них забудем и не удалим их (а мы обычно этого не делаем) - будут освобождены. Скорость разработки в обмен на скорость работы программы.

У Rust нет Garbage Collector, но есть несколько концепций, которые гарантируют, что утечек памяти не будет, и одна из них - это фаза компиляции под названием анализ времени жизни. Именно он видит, что r принимает значение от объекта, время жизни которого закончится раньше, чем будет выведена r - и ругается. В случае с Rust компилятор заставляет разработчика больше думать о коде, но не запускает Garbage Collector. Сложность разработки в обмен на скорость исполнения.

dev notes | golang digest
Telegram dev notes Пишу про Go, Vim, и про то, как я медленно ползу в сторону FAANG. С предложениями: @junsenpub
  • 🔥 8
  • 👾 2
  • 👍 1
More from @junsenior
  1. Sep 28, 2026Сошлись две вещи. Первая - мой проект safemap.ai, про который я уже писал выше - интеракти…
  2. Sep 17, 2026Post #356
  3. Sep 15, 2026Увидел тут в x.com статистику вакансий по PHP и статистику вакансий по hh.ru в целом. Я на…
  4. Sep 12, 2026Вдохновившись проектом, где делали интерактивную карту с тем, как работает Postgres (писал…
  5. Sep 8, 2026OpenAI выложили блогпост https://openai.com/index/navier-stokes-solution/ Мы публикуем реш…
  6. Sep 8, 2026Если кто не знал, вокруг этого сейчас разгорается очень большой скандал с OpenAI. Кратко,…
Threads Profile ViewerView any public Threads profile without an account.Open ThreadLook →Writing with AI? Make it sound human.Metric37 rewrites AI drafts so they read naturally. Free AI detector, 1,500 words free.Try Metric37 →