Как стать автором
Обновить

Комментарии 7

Осталось взять GitHub Copilot, замкнуть их друг на друга и можно идти на заслуженную пенсию.

И действительно, ошибка в том, что сохраняется ссылка на объект, который будет разрушен

... Rust смотрит на такое с недоумением. Без специальных выкрутасов такое невозможно. Код просто не компилируется.

Языки со сборщиком мусора, где тоже "без специальных выкрутасов такое невозможно" появились за 10 лет до С. Печально, что Rust, обеспечивающий аналогичные и столь нужные гарантии, появился только через ~40-50 лет с тех времён.

Утверждать, что Rust обеспечивает "аналогичные и столь нужные гарантии, как GC", это, мягко говоря, understatement. Модель ownership/borrow с концепцией вычисляемых (и энфорсенных) lifetimes на несколько голов выше по утилитарности (пользе), чем просто "сборка мусора".

Во-первых это неожиданно резко показало себя в мире многопоточности. Любой "обычный" язык с GC в условиях многопоточности чувствует себя как Си в мире безопасных указателей. Всё можно и за всё прилетает.

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

ряд ошибочных структур данных просто перестаёт существовать (например, список с циклом).

А почему список с циклом считается ошибочным? Что, если предметная область требует такое (первый пришедший на ум пример - периодические дроби)? Тогда gc справится автоматически, а в Rust (как и в С) придётся писать мудрёные деструкторы, что говорит не в пользу последних. Или в Rust можно как-то системой времён жизни выразить список с циклом? Многопоточность - тоже не всегда аргумент.

Список с циклом называется граф. А ошибочным список с циклом является в том, что не ясно кто именно освобождает узел, на который ссылаются два элемента списка. (для удобства назовём их "прямой" и "загибающий").

Если "прямой" узел решает освободить потомка, и переключиться на следующий узел, то он никак не рассчитывает на то, что кто-то ещё содержит в себе ссылку (которая после этого начинает указывать "в никуда"). Типовая сишная проблема, dangling pointer.

Структура с кольцом вполне может быть, но в момент её создания кто-то должен ответить, что делать, если элемент освобождают, но на него несколько ссылок. Можно, например, Rc (в Rust) использовать. Если элемент "освобождают", то он уменьшает число ссылок внутри себя. Как только становится ноль - самоликвидируется.

И хороший компилятор (Rust, Rust) просто не даст скомпилировать код, в котором возможен dangling pointer; то есть заставит использовать структуры, которые обрабатывают все такие ситуации.

Зарегистрируйтесь на Хабре, чтобы оставить комментарий