Комментарии 16
И чего? Про что статья? Про то что Rust позволяет сделать утечьку памяти?
Memory leaks are memory safe
Во-вторых, функция имеет говорящее название
leak
, и в её описании можно прочитать следующее (обратите внимание на 1-е и 2-е предложения):This function is mainly useful for data that lives for the remainder of the program’s life. Dropping the returned reference will cause a memory leak. If this is not acceptable, the reference should first be wrapped with the Box::from_raw function producing a Box. This Box can then be dropped which will properly destroy T and release the allocated memory.
В третьих, строго говоря, утечка памяти — только лишь подвид проблем с исчерпанием ресурса. Можно без особого труда забить диск на 100%, хоть это и сложнее сделать случайно (впрочем, нагрузочные тесты в сочетании с обильным логированием делают это на раз-два).
В-четвёртых — это, пожалуй, единственный способ вернуть ссылку на не-статический объект, при этом не используя unsafe и не ссылаясь (хех) на аргументы функции.
Ну и в-пятых — это же наколеночный пример. На практике никто не будет
leak
ать память почём зря, тем более чтоб вернуть тип, который имплементирует Copy
.Статья про мотивы разработчиков компиляторов. Про причины того, что мы имеем то, что имеем. Про то, как продажа ещё не доделанного добралась до программирования. Про то, как деньги правят Миром и ведут его к гибели, если угодно.
Мне одному кажется, что примеры на rust компилируются только потому, что реальный аргумент-ссылка не используется в возвращаемом значении?
В этом и смысл: в обоих случаях "хороший" метод Create не использует аргумент-ссылку в возвращаемом значении.
Но компиляторы rust и c# "не залезают" в методы при вызове. Так что понять, будет ли в возвращаемом значении ссылка, которую мы передаем, можно только по сигнатуре метода.
И вот как модифицируется сигнатура метода, чтобы избежать false negative при вызове, описано в статье :)
Не очень понятно что вы имеете ввиду под «не залезают». В rust borrow checker проверит все lifetime и их сходимость в теле функции.
Есть правило lifetime elision, по которому если пропущен явный lifetime у аргумента и возвращаемого значения, то подразумевается, что он один и равен аргументу. Вы просто отвязали аргумент-ссылку от возвращаемой структуры, как того и требует сигнатура.
Я к тому что при вызове метода в compile time учитывается только сигнатура метода: параметры, возвращаемое значение, lifetimes (в том чисте заэлиженые), обобщения.
То что происходит внутри метода вызывающий код не волнует.
Начиная с net7/c# 11 "плохой" пример из статьи с висячей ссылкой не скомпилируется https://learn.microsoft.com/en-us/dotnet/csharp/whats-new/breaking-changes/compiler breaking changes - dotnet 7
Не проверял в живую, но очень странно. что первый пример на Rust скомпилировался. Метод create не накладывает ограничение на время жизни, т.е. на выходе из него должна быть MyStruct<'static>, не?
Когда впервые попробовал `ref struct` в деле, сразу Rust вспомнился. Отличная статья, спасибо. Помогла осознать scoped
.
Rust vs C#: два способа решить проблему ссылок в структурах