rust для чего используется

Rust очень любят, но что в нём особенного?

Rust оказывается самым любимым языком по версии StackOverflow шесть лет подряд. В чём его секрет? Короткий ответ — Rust избавлен от болевых точек, которые есть во многих современных языках программирования.

Мы рассмотрим несколько примеров того, как Rust справляется с проблемами других языков и его недостатки, которые тоже присутствуют.

Наследник динамически типизированных языков

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

Развитие таких языков, как TypeScript и наличие таких возможностей, как аннотации типов в Python, свидетельствуют о том, что люди разочаровались в текущем состоянии динамической типизации.

Статически типизированные языки позволяют использовать ограничения на данные и их поведение, проверяемые компилятором, что снижает когнитивные издержки и недопонимание.

Однако не все способы статической типизации эквивалентны. Многие статически типизированные языки поддерживают концепцию NULL.

Это значит, что любое значение может отсутствовать, таким образом создавая второй возможный тип для каждого типа. Как Haskell и некоторые другие современные языки программирования, Rust реализует эту возможность с помощью типа optional, и компилятор требует, чтобы вы указывали case None.

Это предотвращает возникновение ошибки: TypeError: Cannot read property ‘foo’ of null во время выполнения программы, вместо этого ошибка появляется ещё во время компиляции, и вы можете устранить её до того, как пользователь ее увидит. Вот пример функции для приветствия кого-либо независимо от того, знаем мы его имя или нет; если бы мы забыли случай None в match или попытались использовать имя так, как если бы оно было всегда присутствующим строковым значением, компилятор выдал бы ошибку.

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

Хотя это удобно в начале разработки, снижается способность компилятора предоставлять полезную информацию об ошибках, в случае несовпадения типов. Rust учится на обоих этих стилях и требует, чтобы элементы верхнего уровня, такие как аргументы функций и константы, имели явные типы, позволяя при этом выводить типы внутри тел функций. В этом примере компилятор Rust может определить тип дважды, 2 и 1, поскольку параметр val и возвращаемый тип объявлены как 32-разрядные целые числа со знаком.

Наследник языков со сборщиком мусора

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

Rust позволяет выбирать между хранением данных в стеке или в куче и во время компиляции определяет что память больше не нужна и может быть очищена. Это позволяет эффективно использовать память. Tilde — один из первых пользователей Rust в своем продукте Skylight, обнаружил, что им удалось сократить использование памяти с 5 ГБ до 50 МБ, переписав некоторые конечные точки HTTP на Java в Rust. Такая экономия становится особенно значимой, когда облачные провайдеры меняют цены на дополнительную память.

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

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

Наследник языков системного программирования

Большинство людей рассматривают Rust как альтернативу таким языкам системного программирования, как Си или C++. Самое большое преимущество Rust — это проверка заимствований. Это часть компилятора, ответственная за то, чтобы ссылки не переживали данные, на которые они ссылаются, это помогает устранить целые классы ошибок, вызванных небезопасным использованием памяти.

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

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

Использование небезопасного Rust должно быть обдуманным решением, поскольку его правильное использование требует столько же размышлений и осторожности, как и в любом другом языке, в котором вы несете ответственность за предотвращение неопределенного поведения. Сведение к минимуму небезопасного кода — лучший способ свести к минимуму возможности сбоев и уязвимостей из-за небезопасности памяти.

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

Экосистема Rust

Rust больше, чем спецификация языка и компилятор; многие аспекты создания и поддержки программного обеспечения промышленного качества рассматриваются как объекты первого класса. С помощью rustup можно установить несколько параллельных цепочек инструментов Rust и управлять ими. Rust поставляются с Cargo — инструментом командной строки для управления зависимостями, запуска тестов, создания документации и многого другого. Поскольку зависимости, тесты и документация доступны по умолчанию, их использование широко распространено. crates.io — это сайт сообщества для обмена и поиска библиотек Rust. Любая библиотека, опубликованная в crates.io будет иметь свою документацию на docs.rs.

Кроме встроенных инструментов, коммьюнити Rust создало множество средств разработки. Бенчмаркинг, анализ и тестирование на основе свойств — все это легко легко использовать в проектах. Дополнительные линты компилятора доступны в Clippy, а автоматическое форматирование обеспечивается rustfmt. Поддержка IDE хороша и с каждым днем становится всё более эффективной.

Rust имеет яркое, гостеприимное сообщество. Существует несколько официальных и неофициальных способов получить помощь, таких как чат, форум, сабреддит Rust и, конечно же, Stack Overflow. У Rust есть кодекс поведения, который соблюдается потрясающей командой модераторов, поэтому официальные порталы и большинство неофициальных располагают к себе.

В оффлайне Rust проводит множество конференций по всему миру, таких как RustConf, Rust Belt Rust, RustFest, Rust Latam, RustCon Asia и другие.

Не всё так просто

Сильная система типов Rust и акцент на безопасность памяти — все это происходит во время компиляции — означают, что при компиляции кода чрезвычайно часто возникают ошибки. Это может быть неприятным для программистов, не привыкших к такому самоуверенному языку программирования. Тем не менее, разработчики Rust потратили большое количество времени на работу над улучшением сообщений об ошибках, чтобы убедиться, что они понятны и применимы.

Особенно часто можно услышать, как кто-то жалуется, что он «борется с проверкой заимствований». Хотя эти ошибки могут обескураживать, важно признать, что каждое из выявленных мест потенциально могло привести к ошибкам и потенциальным уязвимостям.

В этом примере мы создаем изменяемую строку, содержащую имя, затем берем ссылку на первые три байта имени. Мы пытаемся изменить строку, очистив ее. Теперь ссылки на действительные данные и их разыменование могут привести к неопределенному поведению, поэтому компилятор останавливает нас:

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

Прототипирование в Rust может быть сложными из-за его статически типизированной природы и из-за того, что Rust требует покрытия 100% условий. Крайние случаи должны быть описаны, даже если программист еще не знает, что там должно быть. На ранних стадиях разработки эти крайние случаи часто можно устранить, вызвав сбой программы, а затем можно добавить строгую обработку ошибок на более позднем этапе. Это другой рабочий процесс, он встречается в таких языках, как Ruby, где разработчики часто пробуют код в REPL, а затем переносят его в прототип, вообще не рассматривая случаи ошибок.

Rust все еще относительно новый язык, а это значит, что некоторые нужные библиотеки могут быть ещё недоступны. Положительным моментом является то, что есть много плодородной почвы для разработки этих необходимых библиотек, возможно, даже с использованием последних достижений в соответствующих областях компьютерных наук. Благодаря этому и возможностям Rust некоторые библиотеки Rust, такие как regex, являются лучшими в своем классе на любом языке.

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

Источник

Rust для чего используется

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

Надёжность

Богатая система типов Rust и модель владения гарантируют потокобезопасность и безопасность памяти, и позволяют устранить множество классов ошибок во время компиляции.

Продуктивность

У Rust отличная документация, дружественный компилятор с полезными сообщениями об ошибках и первоклассный инструментарий — интегрированный пакетный менеджер и инструмент сборки, умная мультиредакторная поддержка с автокомплитом, проверками типов, автоформатированием и многим другим.

Создайте это в Rust

В 2018 году, сообщество Rust приняло решение расширить присутствие языка для нескольких областей (смотрите roadmap на 2018 год). Для этого вы можете найти множество высококачественных пакетов и потрясающие руководства о том, как начать.

rust для чего используется. Смотреть фото rust для чего используется. Смотреть картинку rust для чего используется. Картинка про rust для чего используется. Фото rust для чего используется

Командная строка

Быстро создайте инструмент командной строки с помощью надёжной экосистемы Rust. Rust поможет вам с уверенностью поддерживать ваше приложение и с лёгкостью его распространять.

rust для чего используется. Смотреть фото rust для чего используется. Смотреть картинку rust для чего используется. Картинка про rust для чего используется. Фото rust для чего используется

WebAssembly

Используйте Rust для перезарядки вашего JavaScript, по одному модулю за раз. Опубликуйте в npm, упакуйте с webpack и вы готовы к соревнованиям.

rust для чего используется. Смотреть фото rust для чего используется. Смотреть картинку rust для чего используется. Картинка про rust для чего используется. Фото rust для чего используется

Сетевое программирование

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

rust для чего используется. Смотреть фото rust для чего используется. Смотреть картинку rust для чего используется. Картинка про rust для чего используется. Фото rust для чего используется

Встраиваемые системы

Ориентируетесь на устройства с малой производительностью? Нужен низкоуровневый контроль без отказа от высокоуровневых удобств? Rust предоставит это.

Промышленное использование Rust

Сотни компаний по всему миру используют Rust в реальных проектах для быстрых кросс-платформенных решений с ограниченными ресурсами. Такие проекты, как Firefox, Dropbox и Cloudflare, используют Rust. Rust отлично подходит как для стартапов, так и для больших компаний, как для встраиваемых устройств, так и для масштабируемых web-сервисов.

Мой самый большой комплимент Rust — то, что он скучный, и это потрясающий комплимент.

– Chris Dickinson, инженер npm, Inc

– Antonio Verardi, инженер по инфраструктуре

Примите участие

Читай про Rust

Мы любим документацию! Посмотрите книги, доступные онлайн, а также ключевые блоги и пользовательские руководства.

Смотрите про Rust

У Rust сообщества есть отдельный канал на YouTube, где собрано огромное количество презентаций и учебных пособий.

Сделать вклад

Благодарности

Rust не существовал бы без щедрого вклада времени, работы и ресурсов от отдельных лиц и компаний. Мы очень благодарны за поддержку!

Отдельные участники

Корпоративные спонсоры

Проект Rust получает поддержку от компаний через пожертвования для инфраструктуры.

Источник

Что делает Rust универсальным языком программирования

rust для чего используется. Смотреть фото rust для чего используется. Смотреть картинку rust для чего используется. Картинка про rust для чего используется. Фото rust для чего используется

Долгое время Rust позиционировался исключительно как язык для системного программирования. Попытки использовать Rust для высокоуровневых прикладных задач зачастую вызывали усмешку у значительной части сообщества: зачем использовать инструмент в том качестве, на которое он не рассчитан? Какая польза от возни с типами и анализатором заимствований (borrow checker), если есть Python и Java со сборкой мусора? Но другая часть сообщества всегда видела потенциал Rust именно как языка прикладного, и даже находила его удобным в использовании для быстрого прототипирования — во многом благодаря его особенностям, а не вопреки им.

Шло время, и сейчас использование Rust для высокоуровневых прикладных задач вызывает куда меньше споров, чем раньше. Сообщество накопило практический опыт, и практика показала, что у Rust есть свои преимущества в прикладной сфере. Посмотрите, как менялось официальное определение языка, с такого:

Rust is a systems programming language that runs blazingly fast, prevents segfaults, and guarantees thread safety.

Rust — невероятно быстрый язык для системного программирования без segfault’ов и с гарантиями потокобезопасности.

A language empowering everyone to build reliable and efficient software.

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

Думаю, это хорошая иллюстрация смещения акцентов в позиционировании языка.

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

Что понимать под высоким и низким уровнем?

Понятия высокого/низкого уровня, применительно к языкам программирования, уже давно перестали носить абсолютный характер. По сравнению с ассемблером, язык Си — высокоуровневый, а по сравнению с Haskell — низкоуровневый. В случае с Rust ситуация усугубляется тем, что некоторые языковые возможности в нем близки к Haskell, а некоторые — к Си. Чтобы не запутаться, что считать высоким уровнем, а что низким, я предлагаю использовать простое правило: если языковая конструкция скорее выражает что мы делаем в терминах самой задачи, то она более высокого уровня, чем та, которая скорее говорит нам как именно реализуется решение.

Интересно, что с этой точки зрения декларативный подход выше уровнем, чем императивный. Также понятно, что для системного программирования особо важно, чтобы язык мог выражать как нечто работает в системе, потому что именно это как напрямую и есть что главной задачи системного программирования. Можно сказать, что низкоуровневый по отношению к множеству разных задач язык программирования может являться одновременно высокоуровневым предметно-ориентированным языком (DSL) для сугубо системных задач, так как лучшим образом отражает архитектуру системы.

unsafe-блоки

Давайте сразу обратимся к примеру и посмотрим, как в Rust работают итераторы:

Обратите внимание, что структура Iter содержит в качестве своих полей два указателя: ptr и end (строки 2 и 3). Из-за того, что эти указатели — это обычные Си-совместимые указатели (правда NonNull дополнительно требует, чтобы указатель не был нулевым), довольно низкоуровневые ссылочные типы, их время жизни никак не отслеживается borrow checker’ом. Поэтому заданное в объявлении структуры время жизни ссылки ‘a (1) мы вынуждены добавить в «фантомное» поле с типом нулевой размерности PhantomData (4). Иначе время жизни окажется никак не используемым внутри структуры, что приведет к ошибке компиляции. То есть, другими словами: мы хотим сделать безопасный итератор, который ссылается на элементы коллекции, по которой он итерируется, и для того, чтобы он был безопасным, нам нужно учитывать время жизни ссылок. Но наша внутренняя реализация основана на указателях и потому не подразумевает никакого отслеживания времен жизни со стороны компилятора. Поэтому мы должны гарантировать своей реализацией безопасность кода, работающего с указателями (в unsafe-блоках, подобных 5), и тогда можно реализовать безопасный внешний API по всем правилам работы в safe Rust.

Это очень наглядный пример того, что представляет собой Rust на самом деле. Это высокоуровневый, безопасный язык, в котором есть низкоуровневые небезопасные возможности. Тут граница, по которой одно отделяется от другого — это определение типа, а блоки unsafe выступают маркером того, что в реализации используются весьма низкоуровневые и небезопасные средства (на самом деле в общем случае граница проходит через определение модуля: пока в язык не будет добавлена возможность помечать поля как unsafe, потенциально небезопасным становится весь код в пределах модуля, если на поведение unsafe-методов влияет содержимое полей структуры).

Важный вывод, к которому мы здесь приходим, состоит в том, что Rust — самодостаточный язык. Его высокоуровневые возможности вполне реализуются на низком уровне им же самим. И наоборот: из низкоуровневых «кирпичей» в Rust можно конструировать высокоуровневые блоки, скрывая детали реализации за безопасным API.

Теперь должно быть понятно, что unsafe, который тут и там встречается в стандартной библиотеке Rust — это не баг, а фича. Есть довольно популярный упрек к Rust со стороны: дескать, какой же это безопасный и высокоуровневый язык, если у него в std сплошные unsafe-блоки? Он либо тогда должен быть весь unsafe, либо полностью safe. Но преимущество Rust как раз состоит в том, что он позволяет делать и то и другое, при этом отделяя одно от другого. Это одна из причин, почему Rust по-настоящему универсальный язык программирования.

Макросы

Посмотрите, как организуется простейший цикл for на Python:

Они похожи, не правда ли? Но for в Rust — это просто синтаксический сахар к более низкоуровневому представлению. Вот во что разворачивается данный цикл for :

Касательно процедурных макросов: забавно, как возможность делать низкоуровневые вещи открывает языку путь к построению предельно высокоуровневых абстракций. Дело в том, что процедурные макросы в Rust — это своего рода «плагины к компилятору», которые пишутся на самом Rust. Так как Rust — это язык без сборщика мусора, то он может использоваться для создания встраиваемых компонентов. В частности, можно написать динамическую библиотеку, которую подгрузит компилятор при компиляции вашей программы, и которая будет реализовывать ваши собственные расширения языка. Взглянем на пример использования атрибутных процедурных макросов в actix-web :

Здесь #[get(..)] и #[actix_rt::main] — это пользовательские атрибуты, которые приведут при компиляции к преобразованию элементов, на которые они навешены, в соответствии с заданной программой. Вот во что развернется код выше при компиляции:

Здесь макрос позволяет указать разметку в привычном виде, декларативно, на html-подобном языке, с вкраплениями Rust-кода. Похоже на JSX, расширение языка JavaScript. Только Rust изначально обладает средствами для создания подобных расширений, для него они — обычное дело.

Возможности процедурных макросов практически безграничны. Правда, вам самим придется заботиться о семантике, так как макросы работают на синтаксическом уровне, а рефлексии в Rust не предусмотрено. Тем не менее, грамотно написанные макросы могут сильно упростить создание абстракций, специфичных для конкретной предметной области. Таким образом, сам Rust становится низкоуровневым инструментом реализации требуемого высокоуровнего предметно-ориентированного языка, предельно соответствующего решаемой задаче.

В отличие от некоторых высокоуровневых языков (таких как Python), которые служат своего рода «клеем» для низкоуровневых компонентов, написанных на других языках, Rust сам выступает и в роли «клея», и в роли инструмента реализации «склеиваемых» компонентов.

Бесплатные абстракции

Удивительно, насколько наличие абстракций с нулевой стоимостью, даже самых элементарных, упрощает прикладную разработку. Посмотрите на следующий код, который написан на языке, считающимся высокоуровневым:

И сравните с тем, как то же самое поведение реализуется в Rust:

Где вам понятнее, что происходит и где, по-вашему, вероятность ошибиться меньше? Мне кажется, что ответ очевиден.

Числовой тип — это «низкоуровневый» тип, потому что он отвечает на вопрос как значение будет представлено в памяти, а не на вопрос что оно собой представляет в контексте задачи. Но в Rust можно очень легко и элегантно вводить новые типы поверх существующих:

Несмотря на то, что оба значения a и b имеют одинаковое числовое представление, они являются объектами разных типов, и поэтому перепутать и подставить одно значение вместо другого не получится. Этот паттерн называется «Новый тип» (New type), и он совершенно бесплатен в использовании. (Подробнее о преимуществах использования паттерна «Новый тип» вы можете прочитать в замечательной статье Передача намерений.)

«Новый тип», так же как и вообще любая пользовательская структура или перечисление в Rust, может выступать границей раздела нескольких уровней программирования. И чтобы пользователь мог переходить эту границу всегда, когда это удобно для решения его задачи, эти абстракции не должны сами по себе требовать сколь-либо значимых дополнительных расходов. Иначе пользователь будет вынужден чаще пользоваться имеющимися низкоуровневыми типами, вместо того, чтобы создавать на их основе свои, высокоуровневые.

Обобщенные типы

Помимо того, что обобщенные типы избавляют от написания шаблонного кода, они являются отличным инструментом абстрагирования и высокоуровневой спецификации поведения. Вот что я имею в виду:

Выглядит как что-то низкоуровневое. Но такое поведение часто реализует определенное требование самой задачи. Например, у нас есть тип с приватным конструктором:

Можно сделать так, что UserId будет возможно сконструировать только с помощью некоего сервиса, который либо выдает новое число из глобальной последовательности идентификаторов, либо десериализует значение UserId из ранее сконструированного и сохраненного. (Подробнее о преимуществах подобного подхода к проектированию типов вы можете прочитать в статье Парсите, а не валидируйте.)

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

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

Перечисление типов

АТД во многих случаях избавляет программиста от написания низкоуровневого кода для проверки целостности и непротиворечивости типов данных. Что актуально не только для языков с динамической типизацией, но и для статически типизированных языков.

Вообще, enum в Rust используется чуть менее, чем везде — и это прекрасно! Потому что АТД — это абстракция очень высокого уровня, сравнимая с наследованием классов и полиморфизмом подтипов в ООП. Выражение традиционно низкоуровневых концепций в терминах АТД неожиданно делает их не такими уж и низкоуровневыми.

Вот как решается проблема реализации отсутствующего значения в Rust:

Подробнее об АТД и преимуществах их использования, вы можете прочитать в статье Романа Душкина «Алгебраические типы данных и их использование в программировании».

Владение

Концепция владения в Rust постулирует единственность владельца ресурса в любой момент времени. Она вводилась для решения проблемы гонки данных при конкурентном доступе и проблемы использования памяти после освобождения. Однако кроме этого, концепция владения позволила легко реализовать механизм автоматического освобождения ресурсов, где ресурсом может выступать не только память, но также файлы, сокеты и любые другие пользовательские объекты. Если владелец ресурса всегда один, то когда он выходит из области видимости и уничтожается — ресурс автоматически освобождается. Пользователь может задавать собственную процедуру освобождения, реализуя типаж Drop для своего типа.

В Java, например, с try-with-resources ответственность за корректное освобождение ресурсов перекладывается на вызывающую сторону. К тому же не всегда использование ресурсов настолько локализовано, что безошибочное использование try-with-resources очевидно. Использование Cleaner улучшает ситуацию и избавляет пользователя от необходимости следить за освобождением в тривиальных случаях, но в более сложных — головной боли не избежать (подробнее о проблемах освобождения ресурсов в Java смотрите в лекции Евгения Козлова «Вы все еще используете finalize()? Тогда мы идем к вам»).

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

Дополнительно, с концепцией владения тесно связан принцип перемещения по-умолчанию: если вы передаете владельца из одного места в другое, то ресурс будет перемещен (логически), а не скопирован. Это удобно использовать при реализация всевозможных переходов, например, между состояниями абстрактного автомата:

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

Заимствование

На низком уровне заимствование означает получение ссылки на объект, время жизни которой компилятор проверит на соответствие времени жизни исходного объекта. Но при взгляде с более высокого уровня, заимствование означает получение некоего представления (view), временно соотнесенного с исходным объектом. Такое представление не обязано быть единственным.

Что же в итоге?

Как видите, Rust — это не просто очередной системный язык программирования по мотивам Си. На системный язык, обогащенный рядом высокоуровневых концепций, можно смотреть и с другой стороны: как на прикладной язык, снабженный низкоуровневым инструментарием.

Полезны ли эти низкоуровневые инструменты в прикладной раработке? Я думаю, что да. Они позволяют создавать новые эффективные высокоуровневые абстракции, расширяя арсенал разработчика. Дополнительно, наличие средств, которые позволяют изолировать и связывать между собой разные уровни, делают Rust по-настоящему универсальным языком программирования.

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

Upd.: Отдельное спасибо T_12 за вычитку текста статьи и дельные замечания.

Источник

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *