Времена жизни в Rust

  Рет қаралды 2,743

Bitωise

Bitωise

3 ай бұрын

В этом видео мы поговорим о временах жизни в языке программирования Rust.
На эту тему в интернете существует огромное количество материала, но каждый понимает её по-своему - в основном неправильно.
Я постарался собрать и передать максимально простым способом основную суть времён жизни, или лайфтаймов в Rust. Для этого хорошо подходит визуализация:
- синий прямоугольник обозначает время жизни структуры с момента вызова конструктора до момента её удаления в конце функции, которая ей владеет - все жёлтые и красные области лайфтаймов должны быть внутри синей области жизни самой структуры;
- жёлтый прямоугольник обозначает время жизни немутабельной ссылки на эту структуру - от момента её взятия до последнего использования. Все немутабельные ссылки обозначаются одним цветом потому что их лайфтаймы могут пересекаться без проблем;
- красный прямоугольник обозначает время жизни мутабельной ссылки на эту структуру - от момента её взятия до последнего использования. Все лайфтаймы мутабельных ссылок обозначаются разными оттенками красного потому что они не могут пересекаться друг с другом.
----------
boosty.to/bitwiseuwu
github.com/IoaNNUwU
----------
Это видео может быть интересно любому, кто интересуется системными языками программирования, любит изучать низкоуровневые концепции и работу железа - процессора, оперативной памяти, видеокарты. Если вы знаете или хотите изучить языки C++, Go, Zig - Rust станет отличным дополнением, а возможно даже сможет сместить ваш интерес в свою сторону за счёт таких преимуществ, как безопасность памяти, потокобезопасность, современный API. Rust так же станет прекрасным языком, если вы хотите лишь немного прикоснуться к системному программированию, изучить работу железа, но при этом не оставлять высокоуровневые, простые в использовании языки, такие как Python, Java, JavaScript, Kotlin, Lua.
На этом канале вы найдёте множество видео как на тему системного программирования, так и более общих концепций программирования, таких как ООП, системный дизайн и множество других тем, которые стоят того, чтобы их обсудить.

Пікірлер: 47
@bitwiseuwu
@bitwiseuwu 7 күн бұрын
Несколько правок: 6:40 - В C++ присутствует unique_ptr - аналог Box в Rust. Он позволяет автоматически очищать память, поэтому Box эквивалентен именно unique_ptr. Однако пример в видео скорее про то, что в С++ самый очевидный способ аллоцировать что-либо в куче является небезопасным, а сам unique_ptr требует особого обращения, когда в языке Rust структура Box подчиняется обычным правилам владения, как и все остальные структуры, поэтому автоматический менеджмент памяти происходит по умолчанию. Спасибо @user-nf8zb4qp6j и @8Johnny8Catsvill8 за замечание.
@kittenlord3572
@kittenlord3572 13 күн бұрын
Для меня очень важным выводом из этого видео стало то, что одинаковые обозначения лайфтаймов это не равенство, а что-то сродни подмножеству/меньше-равну. У нас есть лайфтайм 'a, все ссылки обозначенные 'a живут меньше или равно "слабейшему звену" лайфтайма 'a, смысл чего заключается в том, что эти ссылки зависимы от аргументов 'a. Собственно, тогда становится тривиальной логика в примере с choose_greater_number_in_each_pair - первый элемент тупла зависит от первой пары, второй элемент - от второй, обозначить их всех одним лайфтаймом было бы семантически некорректно, ибо они никак не переплетаются Спасибо за отличное видео!
@8Johnny8Catsvill8
@8Johnny8Catsvill8 13 күн бұрын
Пример с C++ полукорректный. Всё действительно так, но сравнивать сырые указатели с Box неправильно. Корректно сравнивать Box с unique_ptr и Arc с shared_ptr. Ибо не нужно забывать, что в Rust тоже есть сырые указатели.
@maximfukalov9106
@maximfukalov9106 7 күн бұрын
И вообще чрезмерно много пафоса против C++ ))
@atommixz
@atommixz 10 күн бұрын
На борроучекере я поплыл
@Thesinter1
@Thesinter1 6 күн бұрын
Очень годно на самом деле. Молодец!
@random6959
@random6959 2 ай бұрын
Спасибо за видео, качественный контент. Удачи в твоих начинаниях!
@liz2k
@liz2k 19 күн бұрын
Да, стало чуть-чуть понятнее, спасибо :)
@DiabloSat_off
@DiabloSat_off 14 күн бұрын
Ура, наконец-то норм канал по расту нашел
@user-kx5ih9kw1x
@user-kx5ih9kw1x 3 ай бұрын
Интересно!
@rm-rf_
@rm-rf_ 14 күн бұрын
Видео огонь.🔥 Хз может ли кто-то более доступно обьяснить чем ты)
@ainr_dev
@ainr_dev 19 күн бұрын
Спасибо!
@AlexAlex-jk2tn
@AlexAlex-jk2tn 7 күн бұрын
Абсолютно некорректный пример из С++, я такой же могу и на расте написать. Использование new/delete в современном C++ это моветон, вы не должны их использовать, если от вас не требуется залезать в "кишки" языка, например если вы реализуете свою собственную реализацию стандартной библиотеки С++. Т.е. обычные программисты должны использовать std::array, std::unique_ptr и т.д., но нельзя использовать new. Некоторые библиотеки типа Qt могут требовать использование new, но они сами управляют памятью. В общем такой себе пример, лучше бы взяли в прмер язык C, где действительно с этим была проблема, а С++ в этом плане такой же безопасный как и Rust.
@user-nf8zb4qp6j
@user-nf8zb4qp6j 18 күн бұрын
А разве альтернативой кода с Box для cpp не будет ли демонстрация использованя unique_ptr, а не просто ручное выделение памяти?
@bitwiseuwu
@bitwiseuwu 18 күн бұрын
Я согласен, что альтернативой Box был бы unique_ptr, но пример был рассчитан на то, что в Rust автоматический менеджмент памяти - это дефолт, а в С++ самый очевидный способ аллоцировать что-либо в куче (слово new) использует ручной менеджмент, а специальные конструкции типа unique_ptr требуют особого подхода и не так удобны как обычные указатели.
@pavel_luck
@pavel_luck Ай бұрын
Интересно, в C# с недавним введением ссылочных структур тоже появились более упрощенные правила контроля жизни ссылок
@bitwiseuwu
@bitwiseuwu Ай бұрын
Не знаком с языком C#, но обязательно почитаю. Вообще идея языка со сборщиком мусора, в котором для производительности можно писать похожий на Rust код со временами жизни - простая и гениальная. Ждём пока кто-нибудь предложит хорошую реализацию!
@pavel_luck
@pavel_luck Ай бұрын
@@bitwiseuwu Для этого используется ключевое слово scoped, которое применяется к переменным ref struct
@ilyasokolov9058
@ilyasokolov9058 18 күн бұрын
и все же зря они не ввели возможность явного ограничения лайфтаймов. Из-за этого в некоторых редких случаях можно получить все те же use after free, доступ к не инициализированной памяти и прочие радости в safe rust.
@user-qt5hy3vn5p
@user-qt5hy3vn5p 18 күн бұрын
Ты как из палаты выбрался?
@ilyasokolov9058
@ilyasokolov9058 18 күн бұрын
@@user-qt5hy3vn5p а может все же ты из палаты сбежал?
@ilyasokolov9058
@ilyasokolov9058 17 күн бұрын
@@user-qt5hy3vn5p поищи, например, крейт cve-rs и давай ко мне в палату =))) там компилятор ломается через тип && () и функции pub const fn lifetime_translator(_val_a: &'a &'b (), val_b: &'b T) -> &'a T - все сводится к получению поведения unsafe std::mem::transmute в safe Rust. И вся проблема в немноголословности лафтаймов, из-за чего 'a и 'b становятся 'static и ссылка остаются после дропа значения
@tgitw-tq6iu
@tgitw-tq6iu 17 күн бұрын
@@ilyasokolov9058 Проблема не в том в чём ты узнал из видосика/статеек, а в том что без этого ансейф-хаки не работают из которых раст состоит на 98%. А ошибка там не в том что получается статик, а в дырявости системы типов вернее в её отсутствии. лайфтайм от лайфтайма как и любой другой генерик стирает тип и потому по определению не является корректным. Далее там противоречие происходит ошибка. Через static-хак много чего делается и он потому существует. В рамках эти преобразований ничего не проверяется. Вернее есть костыль который делает вид что он что-то проверяет, но это не так. Проще всего понять через тот же ансейф. Ансейф это каст чего угодно во что угодно. Да, ты можешь добавить немного проверок в рамках этого каста, но работать они будут для ограниченного случая.
@user-mi6kq5ff8r
@user-mi6kq5ff8r Ай бұрын
А чем отличается время жизни 'a (или любое другое произвольное имя) и время жизни 'static?
@bitwiseuwu
@bitwiseuwu Ай бұрын
'static - это короткая запись для лайфтайма, который не зависит ни от каких других параметров. Можно думать о 'static ссылке как о ссылке с бесконечным лайфтаймом. Например Box::leak возвращает ссылку которая валидна до конца работы программы, потому что данные за этой ссылкой очищаются только при завершении программы. Этот лайфтайм обозначается 'static. То же самое важное при многопоточном программировании. Если лайфтайм не зависит от других параметров, то можно безопасно использовать эту ссылку так долго, как мы этого хотим.
@miron5733
@miron5733 19 күн бұрын
А в чем проблема в примере на c++ создать юзера на стэке, а затем передавать в функцию по ссылке
@ggnet-lm7pg
@ggnet-lm7pg 19 күн бұрын
Сделать то можно, но если со стека удалят юзера, а кто-то обратится по ссылке, то получит segfault в лицо.
@tgitw-tq6iu
@tgitw-tq6iu 17 күн бұрын
@@ggnet-lm7pg Куда и кто что-то удалить со стека?
@AlexAlex-jk2tn
@AlexAlex-jk2tn 7 күн бұрын
@@ggnet-lm7pg Юзера не могут удалить, пока ваша подфункция не завершится, так что никакого segfault'а не возможно, если вы конечно не решите сохранить адрес полученный по ссылке, но вы это же можете сделать и без ссылки: вам передали переменную по значению, а вы куда-то сохранили её адрес, который станет не валидным после завершения функции. В общем следуйте стандартам: нужно сохранить адрес переменной, принимайте указатель (естесственно unique_ptr или shared_ptr), если нужно просто поработать со значением, то принимайте ссылку, если значение занимает меньше машинного слова (int, int32_t, bool и т.п.), то принимайте значение.
@tistaliv1491
@tistaliv1491 Ай бұрын
Если в rust исползуешь Box, то используй в плюсах unique_ptr, а то сравнение очень странное
@bitwiseuwu
@bitwiseuwu Ай бұрын
Смысл этой демонстрации в том, что в Rust нет возможности аллоцировать величину с ручным управлением её временем жизни, тогда как new в C++ - самый простой способ аллоцировать объект в куче - делает именно это. Но я согласен, что преувеличиваю и аналог Box - это unique_ptr в C++. Тут правильнее было бы дать контрпример из языка C, в котором нет умных указателей.
@nanoqsh
@nanoqsh 29 күн бұрын
@@bitwiseuwu аналог new User { 0 } в расте был бы ``` use std::alloc::{alloc, Layout}; unsafe { let layout = Layout::new::(); let ptr = alloc(layout) as *mut User; if ptr.is_null() { panic!("alloc error"); } *ptr = User { id: 0 }; } ``` Но сразу понятно, что это намного более громоздко, требует unsafe-а и вообще никто так писать не будет, хотя технически это возможно.
@AlexAlex-jk2tn
@AlexAlex-jk2tn 7 күн бұрын
@@nanoqsh Открою тайну, за использование new в С++, тоже бьют по рукам. Так что ваш пример с unsafe как раз таки настоящий аналог пример, который автор привёл в видео, а вот unique_ptr правильный вариант. Автору действительно лучше показывать небезопасные моменты в сравнении с языком С, т.к. C++ является прямым конкурентом раста и не менее безопасен чем сам раст, поэтому в нём пофикшены подобные потенциальные проблемы с памятью.
@nanoqsh
@nanoqsh 7 күн бұрын
@@AlexAlex-jk2tn "не менее безопасен чем сам раст" - немного пропустил этот момент. В каком стандарте добавили борроу чеккер в плюсы? Если ни в каком, тогда данное утверждение это полнейшая ложь. Я запросто могу инвалидировать ссылку, инвалидировать итератор, удалить объект на который ссылается span или string_view и так далее. Могу запросто обратиться к элементу большему чем длина массива. Компилятор мне вообще ничего на этот счёт скажет, а просто молча скомпилирует код. Но больше всего мне интересно, зачем обманывать себя и других? Зачем делать вид что плюсы это прям такой же уровень safety что и раст? От чего такая тотальная неприязнь к расту, что лишь бы не писать на нём приходится сочинять подобные небылицы? Язык это просто инструмент, что мешает просто выбрать наиболее эффективный? Ну даже если кому-то и не нужна safety, то ладно, плюсы в этом случае отлично зайдут. Только вот врать зачем?
@AlexAlex-jk2tn
@AlexAlex-jk2tn 6 күн бұрын
@@nanoqsh Т.е. вы утверждаете, что на расте вы себе в ногу прям вообще не можите выстрелить подобным образом? В этом и проблема, что многие боготворители раста приписывают ему сверхбезопасность, но там безопасность на таком же уровне, как и в обычном C++ с использованием санитайзеров и включением соответствующих опций компилятора. Так что да, я утверждаю, что оба языка имеют одинаковый уровень безопасности, который далёк от совершенства, но в целом на любом языке можно натворить себе неприятностей, если захотеть. Сколько я стречал реальных проектов на расте, то обычно это одно из двух: 1. Правильно написанный проект, который по производительности сильно отстаёт от такого же написанного на С++. 2. Проект написанный с упором на производительность, в котором постоянно используются unsafe в итоге у него такая же производительность как у С++, но по безопасности он не лучше чем если бы его сразу на С++ написали. В общем если нужна производительность, то не вижу смысла писать на rust, а если не нужна, то есть куча других языков получше раста.
@GeorgyPlotnikov
@GeorgyPlotnikov 2 ай бұрын
Идея для видео (или серии видео) взять паттерны из GoF и еще какие-нибудь, и сравнить их реализацию на раст и плюсах
@Sneg00vik
@Sneg00vik 20 күн бұрын
Или рассказать какие концепции из книги чистый код актуальны в Rust, а какие потеряли свою актуальность.
@sibkit8183
@sibkit8183 Ай бұрын
Функция не может владеть переменной. Вообще данными на которые указывает переменная вдадеет переменная, разве нет?
@bitwiseuwu
@bitwiseuwu Ай бұрын
Что-то такое я читал в Rust Book, но мне кажется логичной мысль, что все переменные, которые созданы внутри функции не могут её покинуть, если не будут возвращены с помощью return, поэтому можно сказать что функция владеет всеми переменными и даже её аргументами, ведь если аргумент функции передан не по ссылке, то владение над ним переходит функции.
@konstantingavrilov7748
@konstantingavrilov7748 16 күн бұрын
@@bitwiseuwu Тут скорее "владение данными переходит в переменную в другом скоупе"
@norskiy9765
@norskiy9765 2 ай бұрын
Как относишься к плюсам?
@norskiy9765
@norskiy9765 Ай бұрын
Ну и где видео?
@norskiy9765
@norskiy9765 Ай бұрын
Значит живой)
@vladsol5575
@vladsol5575 2 ай бұрын
если никто не понимает значит язык ущербный, нужен язык где всем всё понятно 😂
@tricotazh
@tricotazh Ай бұрын
хорошо
@konstantingavrilov7748
@konstantingavrilov7748 16 күн бұрын
глубоко сказано
@tgitw-tq6iu
@tgitw-tq6iu 17 күн бұрын
Какой же клоун. Типичная мантра на 10 минуте о том, что "одна мутбальная ссылка это про вектор и инвалидацию". Никакого отношения данный пример не имеет к теме и никак не связан с количеством ссылок.
Что такое TCP/IP: Объясняем на пальцах
15:38
Модель OSI | Курс "Компьютерные сети"
11:27
Andrey Sozykin
Рет қаралды 483 М.
Super sport🤯
00:15
Lexa_Merin
Рет қаралды 20 МЛН
ХОТЯ БЫ КИНОДА 2 - официальный фильм
1:35:34
ХОТЯ БЫ В КИНО
Рет қаралды 2,4 МЛН
狼来了的故事你们听过吗?#天使 #小丑 #超人不会飞
00:42
超人不会飞
Рет қаралды 58 МЛН
Java vs Go. Что выбрать?
14:17
Sergey Nemchinskiy
Рет қаралды 53 М.
КАКОЙ ЛИНУКС ВЫБРАТЬ В 2024
24:21
PLAFON - Канал о линуксе
Рет қаралды 460 М.
"Проклятие 35 лет" в Программировании
8:04
Миша Ларченко
Рет қаралды 13 М.
Выложил СВОЙ АЙФОН НА АВИТО #shorts
0:42
Дмитрий Левандовский
Рет қаралды 1,3 МЛН
Как я сделал домашний кинотеатр
0:41
RICARDO
Рет қаралды 1,5 МЛН
Цифровые песочные часы с AliExpress
0:45
Теперь это его телефон
0:21
Хорошие Новости
Рет қаралды 1,7 МЛН