Обновить

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

У меня есть русский перевод книги про атомарность Мары Бос (https://www.chitai-gorod.ru/product/rust-atomarnosti-i-blokirovki-3060006). К сожалению, есть ошибки в переводе смысловые, чтобы их понять и в уме исправить приходится некоторые абзацы перечитывать по несколько раз. Вообще предпочитаю читать в оригинале, т.к. технический английский не такой сложный, как литературный.

Полностью с вами согласен - сам предпочитаю оригиналы. Что касается упомянутой мной книги, то ее перевод (https://dmkpress.com/catalog/computer/programming/978-5-97060-236-2/) мне показался вполне нормальным, исключая забавные ляпы. Например, на странице 60 в одном (!!!) абзаце для управляющего символа escape приводятся два кода: 27 (правильный) и 37. Очевидно, что это ошибка набора. Для опытного программиста это не проблема; для начинающего - засада

Поддержу, хорошая книга. Если кто-то бекендщик, хочет изучить rust и любит подход изучения "сверху вниз", то это будет хорошая входная точка: можно находиться в знакомых абстракциях и в целом понимать что происходит, походу дела выписывать вещи языка, которые использовались и продолжать погружение от них, от часто используемых до редко.

Предпочел бы меньше эмоций и больше примеров. В частности, что не получалось на PHP, примеры ошибок, количественные оценки качества продукта (количество ошибок и т.п.), как быстро пишут код в сравнении 2х языков. И так далее.

А тут удивительно мало конкретики и опыта.

Asynchronous Programming in Rust: Learn Asynchronous Programming by Building Working Examples of Futures, Green Threads, and Runtimes не плохая книга, для общетеоретической подготовки. Читал в оригинале, читается легко.

Hands-On Concurrency with Rust: Confidently Build Memory-safe, Parallel, and Efficient Software in Rust

То же интересная книга, хоть и более старая.

Rust вообще системный язык общего назначения, его и надо с ними сравнивать - C, C++, Pascal, Zig, Odin, Golang, Nim, не понимаю почему вообще сравнивать с Java или Kotlin а тем более PHP, тут только одно может быть сравнение на Kotlin вы найдете работу, на Rust нет, только если не тимлид и прям упретесь перед начальством что это вот пишем на Rust и всё тут

Я много пишу на Python и искренне увидел, что с такой же скоростью можно решать эти же задачи выразительно на Rust, только ошибок меньше, все имеет тип и код работает на порядок быстрее.

Rust после Python странный выбор, всё такие язык не простой, обычного в него бегут плюсовики, посмотрите Mojo

" Те кто не освоил главу №4 будут играть в замечательную игру «Уломай компилятор скомпилировать твой код». Все правила управления памятью, которые делают rust таким мягким и пушистым, заставляют вас думать по другому об устройстве вашей программы. "

@Nurked :)

Когда пишешь сверху вниз, можно хорошо прописать интерфейсы и типы. Но если снизу вверх, проект постепенно сшивается из кусков, сами интерфейсы видоизменяются во времени. Здесь была серия статей про использование Rust в геймдеве и возникающие проблемы упомянутого класса.

Не в упрек языку. Но очень редко плюсы бывают без сопровождающих минусов и соответственно наоборот.

Приложение на Rust ведет себя тут как приложение на C/C++ — выделяет и освобождает память когда нужно.

Что за такой волшебный несуществующий язык C/C++? C не делает этого никогда. Про C++, совершенно другой язык программирования с похожим синтаксисом C, можно сказать то же, пока не реализуешь конструкторы-деструкторы, которые будут вызываться только для автоматических переменных. Автор, по-моему, не знает ни того, ни другого, но сравнивает Rust с ними.

Про C много читал, разные книги, много исходников смотрел. Про C++ много читал, знаю меньше. На обеих не пришлось писать, к сожалению. Начал больше 20 лет назад сразу на Java.

Да, вы правы, конечно, я опечатался, спасибо что заметили. Убрал про C, в нем, конечно, нет деструкторов и нужно ручками "free" вызывать.

Кто нибудь коротко обьяснит - в расте управление памятью сделано через подсчет ссылок и всякого рода смартпоинтеров, или там как то все совсем по другому? А если через подсчет ссылок то как решена проблема циклических ссылок друг на друга?

Проблема циклических ссылок решается сборщиком мусора , которого в Rust нет.

В Rust создание циклических зависимостей достаточно сложный процесс, чтобы на практике этим заниматься только когда действительно необходимо.

Попробую объяснить просто на пальцах. Можно по-разному, гибко, рассказываю от простого к сложному. Компилятор Rust консервативный, иногда перегибает палку и его нужно учиться обходить:

1) "Объекты" создаются обычно в стеке, но могут "взять" себе память в heap.

2) У "объектов", которые "взяли" себе память в heap, обязательно в конце области видимости или в конце их владения (похоже на move-семантику в С++, но безопасная, проверяемая компилятором) вызывается деструктор - компилятором. Компилятор сам вставляет его вызов в бинарку, но в исходниках вызова не видно. По сути похоже на RAII из С++ и по сути такие объекты есть простые smart-pointers (Box).

3) Есть продвинутые "объекты" - smart-pointers, которые не только берут память в heap, но и могут "множится", в т.ч. между потоками и последний такой "объект" удаляет выделенную в heap память. Да, это подсчет ссылок, как и в Swift. Все это проверяется компилятором тоже, безопасно. Это работает с большими издержаками, чем в п.2, поэтому необязательно (Rc, Arc).

4) Можно, через indirection в heap, сделать связанный список, чтобы каждый его элемент был известного для расположения в стеке размер. Так до определенной степени поддерживаются рекурсивные структуры данных типа известного списка "Cons(2):Cons(1)::Null", деревьев и т.п..

5) Когда этого не хватает и нужно больше гибкости, можно динамически связывать "объекты" ссылками в графы через жестко контролируемую компилятором технику внутренней мутабельности (UnsafeCell <- RefCell) и его рантайм контролем ссылок. По умолчанию, ссылки всегда ведут на живые "объекты", может быть одна эксклюзивная (можно менять через нее) или несколько для чтения, но можно это делать динамически и если создашь случайно две эксклюзивные, то программа остановится (контролируемый "крэш" с вызовом деструкторов вверх по стеку - "panic"). Я думаю, это поможет сделать циклические связи в графе "объектов". Не пробовал, если честно.

6) Если не хватило гибкости, всегда есть блок "unsafe", raw-pointers и из них можно что и как угодно собрать, в т.ч. ссылки какие нужны. Может быть придется делать свой локальный сборщик мусора. Но лучше попробовать все способы выше.

Управление памятью реализовано через владение (ownership). Компилятор на этапе _компиляции_ анализирует код и сам вставляет вызовы free (условно) в то место, где владелец данных (переменная) выходит из скоупа (то есть гарантированно больше никто не может ссылаться на данные).

Контейнеры с подсчётами ссылок есть, но используются не часто.

Управление в расте реализовано так же как в плюсах - с использованием RAII на деструторах (они там trait Drop называются), на которых, в частности, смарт поинтеры со счётчиком ссылок работают. А чтобы тяжелее было получить use after free и прочие известные в плюсах штуки, в раст завезли borrow checker - набор правил работы со ссылками, которые проверяются компилятором и не дают случайно выстрелить в ногу.

"Я пишу код с 12 лет и системно занимаюсь коммерческой разработкой с начала нулевых. В основном это Java, Python, PHP, JavaScript и, в последние годы, это Rust. Приходится писать, в основном, mission‑critical системный код..."

Ох уж эти мамкины разрабы с 12 лет. На PHP он пишет mission-critical системый код. Что ещё про PHP мы не знаем?

"Про C много читал, разные книги, много исходников смотрел. Про C++ много читал, знаю меньше. На обеих не пришлось писать..."

"В результате, сейчас, наконец‑то, стало понятно все в деталях, код пишется быстро, задачи решаются легко..." - эти люди, которые вам сказали, что вы пишете быстро и решаете задачи легко - они сейчас здесь, в одной с вами комнате?

Я в принципе, не ожидал ничего нового услышать или увидеть в этой статье и комментах.

Блин, чуваки, иногда язык программирования - всего лишь язык, от того что ты выучишь русский язык, ты не станешь Достоевским, и не станешь писать как Кинг, если выучишь английский. Если ты пишешь как баран, то ты будешь писать как баран свой ужасный код на любом языке.

Я все жду статью про раст от бородатого системного и embedded-разраба, который такой: пишу 20 лет на с, 13 лет на с++, пишу модули для работы с TCP/IP для freebsd, на работе заставили писать на расте, и знаете, вот что я вам скажу...

Это интересно читать, это очень крутой кейс, а не вот эти мамкины программисты с 12 лет. Предлагаю таким разрабам в качестве вступления вставлять в начале статьи ссылку на гитхаб, этого более чем достаточно.

"а не вот эти мамкины программисты с 12 лет" ну не знаю, почему именно мамкины :-) Я еще на Highload регулярно выступаю, если погуглите, видео много. И еще на хабр опубликовал почти 60 постов, по ним понятно, что за проекты и где там "миссион-критикал".

"а не вот эти мамкины программисты с 12 лет" ну не знаю, почему именно мамкины :-) Я еще на Highload регулярно выступаю, если погуглите, видео много. И еще на хабр опубликовал почти 60 постов, по ним понятно, что за проекты и где там "миссион-критикал".

При всех плюсах отсутствия сборщика «мусора» пока, даже в продвинутых Go, С# и Kotlin, он есть, а в Rust — его уже нет. Почему? Потому‑что в Rust сделали очень продвинутый, вобравший в себя множество современных знаний о языках программирования (и известных проблем), компилятор, использующий афинные типы данных (уникальная возможность, о ней в следующий постах), алгебраические «sum/product» типы и «pattern‑matching» по ним, концепции безопасных «shared» и «exclusive» ссылок для оптимизаций ненужных «aliasing» (этой проблеме в современных ЯП не один десяток лет и в Rust ее красиво решили) и строгую систему типов, позволяющую быстро и дешево писать высоконагруженный многопоточный код, работающий со скоростью C/C++ и при этом не «падающий» из за «неопределенного поведения».

"Смешались в кучу кони, люди, колбаса и волчий хер" :D

Начинаете оду расту за отсутствие GC, но это благодаря RAII и деструкторам Drop trait'у, scope'ам и lifetime'ам, и система типов с компилером тут ни при чём, это старо как мир, и не присуще только rust'у. А вот борьба с пресловутым borrow checker'ом как раз выливается в использование Rc/Arc (reference counting), что некоторыми считается аналогом GC (потому что это не-мануальный мемори менеджмент, пусть и не полноценный GC). Афинные и алгебраические типы, паттерн матчинг - это всё для красного словца.

позволяющую быстро и дешево писать высоконагруженный многопоточный код, работающий со скоростью C/C++ и при этом не «падающий» из за «неопределенного поведения».

За наброс на плюсы обидно, наброшу в ответ, напомнив про банальный кейс "rust panics on overflow" :D В плюсах не так много UB, в rust'e своих приколюх хватает, вроде "память течёт? - это не проблема, ведь она не кораптится, значит всё безопасно", и менежмент shared + weak указателей он оставляет на откуп юзеру, благодаря чему люто течёт память в redox и из последнего - в cosmic.

Начинаете оду расту за отсутствие GC, но это благодаря RAII и деструкторам Drop trait'у, scope'ам и lifetime'ам, и система типов с компилером тут ни при чём, это старо как мир, и не присуще только rust'у. А вот борьба с пресловутым borrow checker'ом как раз выливается в использование Rc/Arc (reference counting), что некоторыми считается аналогом GC (потому что это не-мануальный мемори менеджмент, пусть и не полноценный GC). Афинные и алгебраические типы, паттерн матчинг - это всё для красного словца.

Про качество статьи согласен, нафиг такую рекламу Rust. Но вы и сами набрасываете, и довольно нелепо:
- так в каком языке есть лайфтаймы, старые как мир?
- reference counting никак не может считаться аналогом GC, т.к. выполняется сразу за счет деструкторов и RAII.
- магии не существует, и все языки без GC активно используют reference counting (особенно С++), так что в этом плохого?

За наброс на плюсы обидно, наброшу в ответ, напомнив про банальный кейс "rust panics on overflow"

Опция overflow-checks для Cargo.toml существует с выхода Rust 1.0, 10 лет назад.

В плюсах не так много UB

В плюсах столько UB, что их полный список невозможно запомнить. Их буквально несколько сотен. Есть даже целые книги, посвященные UB (https://github.com/Nekrolm/ubbook/, https://pvs-studio.ru/ru/blog/posts/cpp/1129/).

Многие из них крайне не очевидные и не ловятся статическими анализаторами. Санитайзер не поможет в коде, который управляет критически важным оборудованием (АЭС, спутники, самолеты и т.д), т.к. всё уже взорвется/упадёт.

"память течёт? - это не проблема

Это проблема, когда она течет. Но какое отношение это имеет к языку?
Утечку памяти легко организовать через 2 reference counting в любом языке. Предъявляйте претензии к конкретным библиотекам.

И, всё таки, утечка памяти не позволит кому то совершить взлом на лярд долларов, в отличие от UB.

Так как можно сократить путь? Начать я понял с какой книги, а параллельно с ней нужно что-то изучать?

Спасибо за хорошие рекомендации по книгам. Я начал свой переход с PHP на Rust практически одновременно с освоением LLM для кодинга, почти не углубляясь в теорию, из-за чего сейчас у меня на руках относительно работающее приложение в котором понятно не только лишь всё. Как оказалось, задавать ТЗ к Grok (xAI) на русском языке, и получать полноценные модули Rust, очень вызывает привыкание. Сейчас я уже пытаюсь в Cursor побольше проявлять самостоятельного кодинга и контроля, т.к. LLM с огромной легкостью злоупотребляют копипастой, что с типами матрешками вроде Arc<RwLock<Box<dyn Task + 'static>>> создает мягко говоря громоздкий код. С другой стороны, получать документацию и юнит-тесты через чатбот не в пример проще, чем самому заглубляться в рутину. Тем не менее планирую почитать книги, чтобы уметь разбираться хотя-бы в собственных проектах. Сейчас я просто делаю анализатор сделок на бирже, а дальше уже будет действительно критический проект - собственная криптовалюта (блокчейн), где далеко не все получится просто форкнуть.

Могу посоветовать автору обратить внимание на язык программирования Ruby (вместо PHP, а уж тем более Python) - связка Ruby + Rust обещает быть очень перспективной. В Ruby включена поддержка связки с кодом Rust на уровне самой системы языка "bundle gem --ext=rust" - с использованием Magnus (rb_sys).
Сам по себе Ruby уже сейчас использует Rust (для компиляции с поддержкой YJIT требуется установка Rust).
Ruby обладает понятным, логичным и красивым синтаксисом, на Rust можно реализовывать критичные к скорости и безопасности участки кода.

Относительно недавно была издана книга
"Programming Rust SECOND EDITION Fast, Safe Systems Development"
Jim Blandy, Jason Orendorff, and
Leonora F.S. Tindall
(2021 год)
Если какое-то издательство выпустит перевод её - это будет очень полезным материалом для изучения Rust. Первая редакция этой книги - это лучший материал для изучения Rust на русском языке, который я видел.
Я уже написал электронное письмо в издательство ДМК-пресс (они выпустили перевод первой редакции этой книги "Язык программирования Rust" (2018 год)) с просьбой выпустить перевод и второй редакции этой полезной книги. Посмотрим, что получится... Не только же информацией про популярный ныне Питух пытаться кормить всех...

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

Информация

Сайт
www.bitrix24.ru
Дата регистрации
Дата основания
1998
Численность
501–1 000 человек
Местоположение
Россия