Что такое Tokio и Async IO и зачем это нужно?

оригинал: Manish Goregaokar • перевод: bmusin • обучение • поддержите на Patreon

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

Многим из участников сообщества, тем, которые не работали с веб-серверами и связанными с этим вещами, не ясно, чего же мы хотим добиться. Когда эти вещи обсуждались во времена версии 1.0, я тоже имел смутное представление об этом, никогда прежде не работав с этим раньше.

  • Что это такое — Async I/O?
  • Что такое корутины (coroutines)?
  • Что такое легковесные потоки (lightweight threads)?
  • Что такое футуры? (futures)?

  • Как они сочетаются между собой?

Rust: скачиваем ленту и парсим JSON

оригинал: Florian Gilcher • перевод: bmusin • обучение • поддержите на Patreon

Я покажу вам, как написать небольшую программу, которая скачивает ленту (feed) в формате JSON, парсит и выводит список заметок на консоль в форматированном виде.

У нас все вылилось в очень лаконичный код. Как? Смотрите под катом.

Небезопасные абстракции

оригинал: Niko Matsakis • перевод: bmusin • обучение • поддержите на Patreon

Ключевое слово unsafe является неотъемлемой частью дизайна языка Rust. Для тех кто не знаком с ним: unsafe — это ключевое слово, которое, говоря простым языком, является способом обойти проверку типов (type checking) Rust’а.

Существование ключевого слова unsafe для многих поначалу является неожиданностью. В самом деле, разве то, что программы не «падают» от ошибок при работе с памятью, не является особенностью Rust? Если это так, то почему имеется лёгкий способ обойти систему типов? Это может показаться дефектом дизайна языка.

Все же, по моему мнению, unsafe не является недостатком. На самом деле он является важной частью языка. unsafe выполняет роль некоторого выходного клапана — это значит то, что мы можем использовать систему типов в простых случаях, однако позволяя использовать всевозможные хитрые приёмы, которые вы хотите использовать в вашем коде. Мы только требуем, чтобы вы скрывали эти ваши приёмы (unsafe код) за безопасными внешними абстракциями.

Данная заметка представляет ключевое слово unsafe и идею ограниченной «небезопасности». Фактически это предвестник заметки, которую я надеюсь написать чуть позже. Она обсуждает модель памяти Rust, которая указывает, что можно, а что нельзя делать в unsafe коде.

Как публиковать свои пакеты на Crates.io

• Михаил Панков • обучение • поддержите на Patreon

teaser

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

Это цикл статей:

Rust: str vs String

оригинал: Ameya • перевод: Norman Ritchie • обучение • поддержите на Patreon

Будучи новичком в Rust, я запутывался в различных способах представления строк. В книге о языке Rust есть глава «References and Borrowing», в которой используется три различных типа строковых переменных в примерах: String, &String и &str.

Начнём с разницы между str и String: String — это расширяемая, выделяемая на куче структура данных, тогда как str — это неизменяемая строка фиксированной длины, где-то в памяти.

Как настроить сборку и тестирование для Open Source проекта на Rust под Windows с помощью AppVeyor

• Михаил Панков • обучение • поддержите на Patreon

teaser

Как зарегистрироваться на AppVeyor, подключить туда свой проект на Rust и сделать первую сборку.

Это цикл статей:

Как настроить сборку и тестирование для Open Source проекта на Rust под Linux с помощью Travis

• Михаил Панков • обучение • поддержите на Patreon

teaser

Как зарегистрироваться на Travis, подключить туда свой проект на Rust и сделать первую сборку.

Это цикл статей:

Есть ли ООП в Rust?

• Михаил Панков • обучение • поддержите на Patreon

teaser

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

В этой статье мы рассмотрим, как программировать на Rust в ООП-стиле. Мы будем делать это на примере: построим иерархию классов в учебной задаче.

Наша задача — это работа с геометрическими фигурами. Мы будем выводить их на экран в текстовом виде и вычислять их площадь. Наш набор фигур — прямоугольник, квадрат, эллипс, круг.

Передача намерений

оригинал: Jasper 'jaheba' Schulz • перевод: Илья Богданов • обучение • поддержите на Patreon

teaser

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

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

Прекрасные конечные автоматы на Rust

оригинал: Andrew 'hoverbear' Hobden • перевод: Илья Богданов • обучение • поддержите на Patreon

teaser

Последнее время я много размышлял о шаблонах проектирования и приёмах, которые мы используем в программировании. Это и в самом деле прекрасно — начать исследовать проект и видеть знакомые шаблоны и стили, которые ты уже не раз встречал. Это облегчает понимание проекта и даёт возможность ускорить работу.

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

Один интересный шаблон, часто применяемый к таким проблемам — «Конечный автомат». Предлагаю потратить немного времени, чтобы понять, что именно имеется ввиду под этим словосочетанием, и почему же это так интересно.

Графическое описание владения и заимствования в Rust

оригинал: Phil Ruffwind • перевод: Шерзод Муталов • обучение • поддержите на Patreon

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

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

Схема

Числа Пеано на системе типов Rust

• Fedor Logachev • обучение • поддержите на Patreon

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

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

Если верить википедии «Аксио́мы Пеа́но — одна из систем аксиом для натуральных чисел, введённая в XIX веке итальянским математиком Джузеппе Пеано.»

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

  • 1 является натуральным числом
  • Число, следующее за натуральным, тоже является натуральным.

Дословно запишем на rust с помощью:

1
2
3
4
enum Nat {
  Zero,
  Succ(Nat)
}

Nat — это либо ноль, либо следующее натуральное число.

futures-rs: асинхронщина на Rust

оригинал: Alex Crichton • перевод: Арсен Галимов • обучение • поддержите на Patreon

Замечание: проект futures-rs был реорганизован и многие вещи были переименованы. Где возможно, ссылки были обновлены.

Начинаем работу с futures

Этот документ поможет вам изучить контейнер для языка программирования Rust — futures, который обеспечивает реализацию futures и потоков с нулевой стоимостью. Futures доступны во многих других языках программирования, таких как C++, Java, и Scala, и контейнер futures черпает вдохновение из библиотек этих языков. Однако он отличается эргономичностью, а также придерживается философии абстракций с нулевой стоимостью, присущей Rust, а именно: для создания и композиции futures не требуется выделений памяти, а для Task, управляющего ими, нужна только одна аллокация. Futures должны стать основой асинхронного компонуемого высокопроизводительного ввода/вывода в Rust, и ранние замеры производительности показывают, что простой HTTP сервер, построенный на futures, действительно быстр.

Эта документация разделена на несколько разделов:

  • «Здравствуй, мир!»;
  • типаж future;
  • типаж Stream;
  • конкретные futures и поток (Stream);
  • возвращение futures;
  • Task и future;
  • локальные данные задачи.

Futures нулевой стоимости в Rust

оригинал: Aaron Turon • перевод: Сергей Ефремов • обучение • поддержите на Patreon

Замечание: проект futures-rs был реорганизован и многие вещи были переименованы. Где возможно, ссылки были обновлены.

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

Нам бы хотелось чего-нибудь более высокоуровневого, с лучшей эргономикой, но чтобы оно обладало хорошей компонуемостью, поддерживая экосистему асинхронных абстракций, работающих вместе. Звучит очень знакомо: ту же цель преследовало внедрение futures (или promises) во многие языки, поддерживающие синтаксический сахар в виде async/await на вершине.

Мифы и легенды о переполнении целых чисел в Rust

оригинал: Huon Wilson • перевод: Станислав Ткач • обучение • поддержите на Patreon

Примитивные целочисленные типы, поддерживаемые процессорами, являются ограниченным приближением к бесконечному набору целых чисел, которыми мы привыкли оперировать в реальной жизни. Это ограниченное представление не всегда совпадает с «реальными» числами, например 255_u8 + 1 == 0. Зачастую программист забывает об этой разнице, что легко может приводить к багам.

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

Введение в Iron

• Арсен Галимов aka «Loo Maclin» • обучение • поддержите на Patreon

Немного об Iron

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

Философия

Iron построен на принципе расширяемости настолько, насколько это возможно. Он вводит понятия для расширения собственного функционала:

  • «промежуточные» типажи — используются для реализации сквозного функционала в обработке запросов;
  • модификаторы — используются для изменения запросов и ответов наиболее эргономичным способом.

С базовой частью модификаторов и промежуточных типажей вы познакомитесь в ходе статьи.

Создание проекта

Для начала создадим проект с помощью Cargo, используя команду:

1
cargo new rust-iron-tutorial --bin

Большие бинари в моем Rust? (Why is a Rust executable large?)

оригинал: lifthrasiir • перевод: kitsu • обучение • поддержите на Patreon

Это статья — перевод статьи Why is a Rust executable large?

Большие бинари в моем Rust?

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

1
2
3
fn main() {
    println!("Hello, world!");
}

Скомпилировав получим соответствующий исполняемый файл:

1
2
3
$ rustc hello.rs
$ du -h hello
632K hello

632 килобайт для простого принта?! Rust позиционируется как системный язык, который имеет потенциал для замены C/C++, верно? Так почему бы не проверить аналогичную программу на ближайшем конкуренте?

От & str к Cow

оригинал: Joe Wilm • перевод: Алексей Сидоров • обучение • поддержите на Patreon

Эта статья — перевод статьи From & str to Cow за авторством Joe Wilm

От & str к Cow

Одной из первых вещей, которые я написал на Rust’е была структура с &str полем. Как вы понимаете, анализатор заимствований не позволял мне сделать множество вещей с ней и сильно ограничивал выразительность моих API. Эта статья нацелена на демонстрацию проблем, возникающих при хранении сырых & str ссылок в полях структур и путей их решения. В процессе я собираюсь показать некоторое промежуточное API, которое увеличивает удобство пользования такими структурами, но при этом снижает эффективность генерируемого кода. В конце я хочу предоставить реализацию, которая будет одновременно и выразительной и высокоэффективной.

Lock-free без сборки мусора

оригинал: Aaron Turon • перевод: Сергей Ефремов • обучение • поддержите на Patreon

Это перевод статьи.

В нашей среде широко распространена мысль о том, что одним из преимуществ сборщика мусора является простота разработки высоко-производительных lock-free структур данных. Ручное управление памятью в них сделать не просто, а GC с лёгкостью решает эту проблему.

Этот пост покажет, что, используя Rust, можно построить API управления памятью для конкурентных структур данных, которое:

  • Сделает возможным реализацию lock-free структуры данных, как это делает GC;
  • Создаст статическую защиту от неправильного использования схемы управления памятью;
  • Будет иметь сравнимые с GC накладные расходы (и более предсказуемые).

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

Я реализовал схему управления памятью, основанную на эпохах («epoch-based memory reclamation») в новой библиотеке Crossbeam, которая на сегодняшний день готова к использованию с вашими структурами данных. В этом посте я расскажу о lock-free структурах данных, алгоритме эпох и внутреннем API Rust.

Утечки не нарушают безопасность памяти

оригинал: Huon Wilson • перевод: Станислав Ткач • обучение • поддержите на Patreon

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

Проще говоря: нарушение доступа к памяти — это какие-то действия с некорректными данными, а утечка памяти — это отсутствие определённых действий с корректными данными. В табличной форме:

1
2
3
                    Корректные данные     Некорректные данные
Используются        OK                    Ошибка доступа к памяти
Не используются     Утечка памяти         OK

Rust через его основополагающие принципы

оригинал: Ian Whitney • перевод: Станислав Ткач • обучение • поддержите на Patreon

У меня есть несколько мыслей об изучении языков программирования.

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

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

Это очень похоже на обсуждение автомобилей. Слышали о новом УАЗ Рыбак? Насколько он быстр? Смогу ли я проехать на нём через озеро?

Когда мы похожим образом говорим о языках, то подразумеваем, что они взаимозаменяемы. Как машины. Если я знаю, как управлять Ладой Саранск, значит смогу вести и УАЗ Рыбак без каких-либо проблем. Разница только в скорости и приборной панели, не так ли?

Но представьте, как будет выглядеть PHP-автомобиль. А теперь вообразите, насколько будет отличаться автомобиль Lisp. Пересесть с одного на другой потребует гораздо большего, чем усвоить, какая кнопка управляет отоплением.

Работа с С-объединениями (union) в Rust FFI

оригинал: Herman J. Radtke III • перевод: Станислав Ткач • обучение • поддержите на Patreon

Примечание: Эта статья предполагает, что читатель знаком с Rust FFI (перевод), порядком байтов (endianess) и ioctl.

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

Святая Корова! (Holy std: borrow: Cow!)

оригинал: llogic • перевод: Сергей Ефремов • обучение • поддержите на Patreon

На днях я участвовал в обсуждении на reddit того, насколько трудны на самом деле времена жизни. При работе над clippy мне не приходилось до этого времени иметь с ними дела, потому что всем, чем мы пользовались, владел компилятор, особого мнения на этот счёт у меня не было, и тут The_Doculope заявил:

Есть места, в которых опускание времён жизни может укусить нас за задницу.

(/u/The_Doculope на /r/rust)

Честно говоря, я был шокирован!

И вот я, благодарный опусканию времени жизни за то, что освободило меня от лишних переживаний, только что узнал, что оно может укусить меня за задницу. Я начал параноить. ; -P

(я на /r/rust)

Сразу после написания этого, мне попалась строка в исходном коде clippy, которой я был не очень доволен, потому что в ней происходило клонирование строки (с помощью .to_string()! богохульство!) просто для использования её в &format(…). Итак, происходило это в Result<String, …>::unpack_or(…), поэтому сначала я попытался дать обладаемой строке такое же время жизни, как и у полученной, без особого смысла.

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

Я избавлю вас от этих покрытых моей кровью сообщений об ошибках, потому что убеждён — если вы писали код на Rust, вы их знаете наизусть, и, даже наоборот, на самом деле все было не так уж и плохо, потому что, к счастью, я вспомнил такой удобный std::borrow::Cow, а уж переписать сниппет с ним (и std::convert::From) было раз плюнуть. Я даже создал fn для его повторного использования, таким образом, так я официально написал свой первый метод, аннотированный временем жизни. [ДОСТИЖЕНИЕ ОТКРЫТО]

Святая Корова! — Продолжение (Holy std: borrow: Cow! — Redux)

оригинал: llogic • перевод: Сергей Ефремов • обучение • поддержите на Patreon

Последний раз я использовал очень полезный Cow, чтобы разобраться с тем, нужно ли клонировать str или просто заимствовать её. Это было моё первое применение аннотаций времён жизни, и это было явно похоже на достижение. : -)

На /r/rust, пользователь Artemciy спросил меня очень хороший вопрос

[…] Как это работает? Похоже на какую-то магию. Имею ввиду, как String становится str?

А также предложил свой вариант ответа:

P. S. Похоже, что в String есть реализация IntoCow’, которая преобразует её в str, но если посмотреть на эту реализацию — опять какая-то магия. Может String в тайне является str?

(выделено мной)

Хороший вопрос. На самом деле, наверное, вы бы хотели прочитать про обмен догадками, озарение, исследования, неправильные решения и драму в интернете. Но увы! У кого есть на это время? Поэтому попытаюсь донести всю суть от начала и до конца.

Как пользоваться типажами From и Into

оригинал: llogic • перевод: Сергей Ефремов • обучение • поддержите на Patreon

(Эта статья написана для Rust 1.4, и код по-прежнему работает в 1.7 без изменений)

Пришло время поговорить про типажи From и Into (и некоторые с ними связанные) и задать вопрос, где и когда их использовать. Заметьте, что есть ещё специфические типажи (например, IntoIterator) и более конкретные их варианты (например, FromStr); надо быть в курсе всего этого при написании кода на Rust.

Отладка приложений на Rust с помощью GDB

• Александр Яшкин • обучение • поддержите на Patreon

Введение

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

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

1
2
3
4
5
$ rustc -V
rustc 1.7.0 (a5d1e7a59 2016-02-29)

$ gdb --version
GNU gdb (GDB) 7.11

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

Время жизни в Rust (Часть 2)

• Александр Яшкин • обучение • поддержите на Patreon

Введение

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

Постановка задачи

Мы создадим структуру Customer, описывающую покупателя, который должен владеть экземпляром структуры Car. Покупатель будет иметь возможность покупать, продавать и обмениваться с другими покупателями автомобилями.

Время жизни в Rust (Часть 1)

• Александр Яшкин • обучение • поддержите на Patreon

Введение

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

Постановка задачи

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