Для чего нужен rust язык

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 — новый экспериментальный язык программирования, разрабатываемый Mozilla. Язык компилируемый и мультипарадигмальный, позиционируется как альтернатива С/С++, что уже само по себе интересно, так как даже претендентов на конкуренцию не так уж и много. Можно вспомнить D Вальтера Брайта или Go от Google.
В Rust поддерживаются функицональное, параллельное, процедурное и объектно-ориентированное программирование, т.е. почти весь спектр реально используемых в прикладном программировании парадигм.

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

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

Синтаксис языка строится в традиционном си-подобном стиле (что не может не радовать, так как это уже стандарт де-факто). Естественно, всем известные ошибки дизайна С/С++ учтены.
Традиционный Hello World выглядит так:

Пример чуть посложнее — функция расчета факториала:

Как видно из примера, функции объявляются в «функциональном» стиле (такой стиль имеет некоторые преимущества перед традиционным «int fac(int n)»). Видим автоматический вывод типов (ключевое слово let), отсутствие круглых скобок у аргумента while (аналогично Go). Еще сразу бросается в глаза компактность ключевых слов. Создатели Rust дейтсвительно целенаправленно сделали все ключевые слова как можно более короткими, и, скажу честно, мне это нравится.

Мелкие, но интересные синтаксические особенности

Типы данных

Rust, подобно Go, поддерживает структурную типизацию (хотя, по утверждению авторов, языки развивались независимо, так что это влияние их общих предшественников — Alef, Limbo и т.д.). Что такое структурная типизация? Например, у вас в каком-то файле объявлена структура (или, в терминологии Rust, «запись»)
type point = ;
Вы можете объявить кучу переменных и функций с типами аргументов «point». Затем, где-нибудь в другом месте, вы можете объявить какую-нибудь другую структуру, например
type MySuperPoint = ;
и переменные этого типа будут полностью совместимы с переменными типа point.

В противоположность этому, номинативная типизация, принятая в С, С++,C# и Java таких конструкций не допускает. При номинативной типизации каждая структура — это уникальный тип, по умолчанию несовместимый с другими типами.

Структуры в Rust называются «записи» (record). Также имеются кортежи — это те же записи, но с безымянными полями. Элементы кортежа, в отличие от элементов записи, не могут быть изменяемыми.

Имеются вектора — в чем-то подобные обычным массивам, а в чем-то — типу std::vector из stl. При инициализации списком используются квадратные скобки, а не фигурные как в С/С++

Вектор, тем ни менее — динамическая структура данных, в частности, вектора поддерживают конкатенацию.

Есть шаблоны. Их синтаксис вполне логичен, без нагромождений «template» из С++. Поддерживаются шаблоны функций и типов данных.

Язык поддерживает так называемые теги. Это не что иное, как union из Си, с дополнительным полем — кодом используемого варианта (то есть нечто общее между объединением и перечислением). Или, с точки зрения теории — алгебраический тип данных.

В простейшем случае тег идентичен перечислению:

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

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

Сопоставление с образцом (pattern matching)

Для начала можно рассматривать паттерн матчинг как улучшенный switch. Используется ключевое слово alt, после которого следует анализируемое выражение, а затем в теле оператора — паттерны и действия в случае совпадения с паттернами.

В качестве «паттеронов» можно использовать не только константы (как в Си), но и более сложные выражения — переменные, кортежи, диапазоны, типы, символы-заполнители (placeholders, ‘_’). Можно прописывать дополнительные условия с помощью оператора when, следующего сразу за паттерном. Существует специальный вариант оператора для матчинга типов. Такое возможно, поскольку в языке присутствует универсальный вариантный тип any, объекты которого могут содержать значения любого типа.

Указатели. Кроме обычных «сишных» указателей, в Rust поддерживаются специальные «умные» указатели со встроенным подсчетом ссылок — разделяемые (Shared boxes) и уникальные (Unique boxes). Они в чем-то подобны shared_ptr и unique_ptr из С++. Они имеют свой синтаксис: @ для разделяемых и

для уникальных. Для уникальных указателей вместо копирования существует специальная операция — перемещение:

после такого перемещения указатель x деинициализируется.

Замыкания, частичное применение, итераторы

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

1. Ключевое слово lambda используется для объявления вложенной функции или функционального типа данных.

В этом примере мы имеем функцию make_plus_function, принимающую один аргумент «x» типа int и возвращающую функцию типа «int->int» (здесь lambda — ключевое слово). В теле функции описывается эта самая фунция. Немного сбивает с толку отсутствие оператора «return», впрочем, для ФП это обычное дело.

2. Ключевое слово block используется для объявления функционального типа — аргумента функции, в качестве которого можно подставить нечто, похожее на блок обычного кода.

Здесь мы имеем функцию, на вход которой подается блок — по сути лямбда-функция типа «int->int», и вектор типа int (о синтаксисе векторов далее). Сам «блок» в вызывающем коде записыавется с помощью несколько необычного синтаксиса <|x| x + 1 >. Лично мне больше нравятся лямбды в C#, символ | упорно воспринимается как битовое ИЛИ (которое, кстати, в Rust также есть, как и все старые добные сишные операции).

3. Частичное применение — это создание функции на основе другой функции с большим количеством аргументов путем указания значений некоторых аргументов этой другой функции. Для этого используется ключевое слово bind и символ-заполнитель «_»:

Чтобы было понятнее, скажу сразу, что такое можно сделать на обычном Си путем создания простейшей обертки, как-то так:
const char* daynum (int i) < const char *s =<"mo", "tu", "we", "do", "fr", "sa", "su">; return s[i]; >

Но частичное применение — это функциональный стиль, а не процедурный (кстати, из приведенного примера неясно, как сделать частичное применение, чтобы получить функцию без аргументов)

Еще пример: объявляется функция add с двумя аргументами int, возвращающая int. Далее объявляется функциональный тип single_param_fn, имеющий один аргумент int и возвращающий int. С помощью bind объявляются два функциональных объекта add4 и add5, построенные на основе функции add, у которой частично заданы аргументы.

Функциональные объекты можно вызывать также, как и обычные функции.

4. Чистые функции и предикаты
Чистые (pure) функции — это функции, не имеющие побочных эффектов (в том числе не вызывающие никаких других функций, кроме чистых). Такие функции выдяляются ключевым словом pure.

Предикаты — это чистые (pure) функции, возвращающие тип bool. Такие функции могут использоваться в системе typestate (см. дальше), то есть вызываться на этапе компиляции для различных статических проверок.

Синтаксические макросы
Планируемая фича, но очень полезная. В Rust она пока на стадии начальной разработки.

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

Атрибуты

Концепция, похожая на атрибуты C# (и даже со схожим синтаксисом). За это разработчикам отдельное спасибо. Как и следовало ожидать, атрибуты добавляют метаинформацию к той сущности, которую они аннотируют,

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

Параллельные вычисления

Пожалуй, одна из наиблее интересных частей языка. При этом в tutorial на данный момент не описана вообще:)
Программа на Rust состоит из «дерева задач». Каждая задача имеет функцию входа, собственный стек, средства взаимодействия с другими задачами — каналы для исходящей информации и порты для входящей, и владеет некоторой частью объектов в динамической куче.
Множество задач Rust могут существовать в рамках одного процесса операционной системы. Задачи Rust «легковесные»: каждая задача потребляет меньше памяти чем процесс ОС, и переключение между ними осуществляется быстрее чем переключение между процессами ОС (тут, вероятно, имеются в виду все-же «потоки»).

Задача состоит как минимум из одной функции без аргументов. Запуск задачи осуществляется с помощью функции spawn. Каждая задача может иметь каналы, с помощью которых она передает инфорацию другим задачам. Канал — это специальный шаблонный тип chan, параметризируемый типом данных канала. Например, chan — канал для передачи беззнаковых байтов.
Для передачи в канал используется функция send, первым аргументом которой является канал, а вторым — значение для передачи. Фактически эта функция помещает значение во внутренний буфер канала.
Для приема данных используются порты. Порт — это шаблонный тип port, параметризируемый типом данных порта: port — порт для приема беззнаковых байтов.
Для чтения из портов используется функция recv, аргументом которой является порт, а возвращаемым значением — данные из порта. Чтение блокирует задачу, т.е. если порт пуст, задача переходит в состояние ожидания до тех пор, пока другая задача не отправит на связанный с портом канал данные.
Связывание каналов с портами происходит очень просто — путем инициализации канала портом с помощью ключевого слова chan:
let reqport = port();
let reqchan = chan(reqport);
Несколько каналов могут быть подключены к одному порту, но не наоборот — один канал не может быть подключен одновременно к нескольким портам.

Typestate

Общепринятого перевода на русский понятия «typestate» я так и не нашел, поэтому буду называть это «состояния типов». Суть этой фичи в том, что кроме обычного контроля типов, принятого в статической типизации, возможны дополнительные контекстные проверки на этапе компиляции.
В том или ином виде состояния типов знакомы всем программистам — по сообщениям компилятора «переменная используется без инициализации». Компилятор определяет места, где переменная, в которую ни разу не было записи, используется для чтения, и выдает предупреждение. В более общем виде эта идея выглядит так: у каждого объекта есть набор состояний, которые он может принимать. В каждом состоянии для этого объекта определены допустимые и недопустимые операции. И компилятор может выполнять проверки — допустима ли конкретная операция над объектом в том или ином месте программы. Важно, что эти проверки выполняются на этапе компиляции.

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

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

Ограничения (constraints) — это специальные проверки, которые могут выполняться на этапе компиляции. Для этого используется ключевое слово check.

Предикаты могут «навешиваться» на входные параметры функций таким вот способом:

Информации по typestate крайне мало, так что многие моменты пока непонятны, но концепция в любом случае интересная.

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

Источник

Зачем нам нужен Rust?

Для чего нужен rust язык. Смотреть фото Для чего нужен rust язык. Смотреть картинку Для чего нужен rust язык. Картинка про Для чего нужен rust язык. Фото Для чего нужен rust языкRust — системный язык программирования, который исполняется чертовски быстро, предотвращает почти все падения, а также устраняет неопределённости совместного доступа к данным. Он разрабатывается Mozilla как инструмент для создания обозревателя нового поколения — Servo.

Пункты соприкосновения

Данное определение языка кажется сказкой, ибо доступные нам прежде инструменты всегда балансировали между скоростью и надёжностью. С одной стороны — С++, в котором огромные возможности и скорость компенсируются постоянными ошибками доступа вне выделенной памяти, к удалённой памяти, либо неожиданные результаты чтения данных, которые в это время пишет другой поток. С другой стороны есть Haskell, этакий язык-крепость (по принципу «раз оно компилируется, значит работает»), хоть и не могущий похвастаться скоростью. Где-то посередине балансируют Java, Python, C# и другие популярные (в силу своей практичности) языки. Rust же для меня выступает удачным скрещением лучших свойств С++ и Haskell, при этом сохраняя практичность на уровне конкурентов.

Через тернии к звёздам

Вся магия Rust становится возможной благодаря знанию компилятором о том, кто владеет определённой сущностью (owner), кто лишь временно одалживает её (mutable borrow), а кто просто пришёл посмотреть (immutable borrow). Программируя на С++ или Java, Вы всё равно держите в голове эту информацию, пусть и в несколько ином виде. В Rust это выражается языковыми конструкциями, что позволяет компилятору проверить правильность Вашей модели, а также гарантировать её беспроблемное выполнение. Для такого программирования требуется немного иной подход, чем мы привыкли. Попытаюсь пройтись по основным моментам, которые могут занести Вас в ступор при начальном изучении:

1. Нет наследования, зато есть структуры и способности (traits).
2. Указатели есть только в незащищённом коде (unsafe <>). Вместо них в безопасном коде есть ссылки, которые гарантированно указывают на существующие объекты.
3. Если у Вас неизменяемая ссылка на что-то (immutable borrow = &Object), то никто не может изменить значение, пока ссылка жива.
4. Если у Вас изменяемая ссылка (mutable borrow = &mut Object), то никто другой не может читать содержимое объекта, пока ссылка жива.
5. Разработчики языка предпочитают Mac и *nix, так что для работы под Windows нужна GNU среда.

У Rust очень весёлое и активное сообщество, Вам всегда будут рады на канале IRC и в Reddit. Уже написано приличное количество всякого добра, многие из проектов активно развиваются на GitHub. Особой популярностью язык пользуется у разработчиков игр и графики. Есть зачатки операционных систем. В перспективе также маячит возможность исполнения на веб-серверах и клиентах. Rust подходит для любых задач!

Единственная на сегодня, пожалуй, серьёзная проблема языка — это его бурное развитие. От версии к версии может меняться синтаксис, порой приходится переосмысливать логику, подстраиваясь под новые возможности языка. Такая ситуация продлится ещё какое-то время в этом году, пока не появится Rust-1.0. А тем временем журнал Rust ‘n Stuffs в еженедельной рубрике This Week in Rust оповещает нас обо всех прошедших и готовящихся изменениях, о новых статьях и перспективных проектах.

Немного обо мне

Скоро будет уже 2 года, как я перешёл на Rust, оставив позади Boo, Dart, Haskell и, конечно, С++. Первым проектом была игра, которую решил отложить до выхода стабильной версии языка. Сейчас активно работаю над rust-compress и своим компрессором данных. Верю в светлое будущее Rust и приглашаю всех принять участие!

Источник

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

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