Программирование на Rust.
9781718500440
267
88
5MB
Russian
Pages [592]
Year 2021
Report DMCA / Copyright
DOWNLOAD DJVU FILE
Table of contents :
Вступление
Предисловие
Благодарности
Об авторах
Введение
Кому подойдет язык Rust
Команды разработчиков
Студенты
Компании
Разработчики открытого исходного кода
Люди, ценящие скорость и стабильность
Для кого эта книга
Как пользоваться этой книгой
Ресурсы
От издательства
Глава 1. Начало работы
Установка
Установка инструмента rustup в Linux или macOS
Установка инструмента rustup в Windows
Обновление и деинсталляция
Устранение неисправностей
Локальная документация
Здравствуй, Мир!
Создание каталога проектов
Написание и выполнение программы Rust
Анатомия программы на языке Rust
Компиляция и выполнение являются отдельными шагами
Здравствуй, Cargo!
Создание проекта с помощью Cargo
Построение проекта Cargo и его выполнение
Сборка для релиза
Cargo как общепринятое средство
Итоги
Глава 2. Программирование игры-угадайки
Настройка нового проекта
Обработка загаданного числа
Хранение значений с помощью переменных
Обработка потенциального сбоя с помощью типа Result
Печать значений с помощью заполнителей макрокоманды println!
Тестирование первой части
Генерирование секретного числа
Использование упаковки для получения большей функциональности
Генерирование случайного числа
Сравнение загаданного числа с секретным числом
Вывод нескольких загаданных чисел с помощью цикличности
Выход из игры после правильно угаданного числа
Обработка ввода недопустимых данных
Итоги
Глава 3 Концепции программирования
Переменные и изменяемость
Различия между переменными и константами
Затенение
Типы данных
Скалярные типы
Составные типы
Функции
Параметры функций
Инструкции и выражения в телах функций
Функции с возвращаемыми значениями
Комментарии
Управление потоком
Выражения if
Повторение с помощью циклов
Итоги
Глава 4. Концепция владения
Что такое владение?
Правила владения
Область видимости переменной
Строковый тип
Память и выделение пространства
Владение и функции
Возвращаемые значения и область видимости
Ссылки и заимствование
Изменяемые ссылки
Висячие ссылки
Правила ссылок
Срезовый тип
Строковые срезы
Другие срезы
Итоги
Глава 5. Использование структур для связанных данных
Определение и инстанцирование структур
Использование краткой инициализации полей: когда у переменных и полей одинаковые имена
Создание экземпляров из других экземпляров с помощью синтаксиса обновления структуры
Использование кортежных структур без именованных полей для создания разных типов
Unit-подобные структуры без полей
Пример программы с использованием структур
Рефакторинг с использованием кортежей
Рефакторинг с использованием структур: добавление большего смысла
Добавление полезной функциональности с использованием типажей с атрибутом derived
Синтаксис методов
Определение методов
Методы с большим числом параметров
Связанные функции
Несколько блоков impl
Итоги
Глава 6. Перечисления и сопоставление с паттернами
Определение перечисления
Выражение match как оператор управления потоком
Паттерны, которые привязываются к значениям
Сопоставление с Option
Совпадения являются исчерпывающими
Заполнитель _
Сжатое управление потоком с помощью if let
Итоги
Глава 7. Управление растущими проектами с помощью пакетов, упаковок и модулей
Пакеты и упаковки
Определение модулей для управления областью видимости и конфиденциальностью
Пути для ссылки на элемент в дереве модулей
Демонстрация путей с помощью ключевого слова pub
Начало относительных путей с помощью super
Обозначение структур и перечислений как публичных
Введение путей в область видимости с помощью ключевого слова use
Создание идиоматических путей use
Предоставление новых имен с помощью ключевого слова as
Реэкспорт имен с использованием pub
Использование внешних пакетов
Использование вложенных путей для очистки больших списков use
Оператор glob
Разделение модулей на разные файлы
Итоги
Глава 8. Общие коллекции
Хранение списков значений с помощью векторов
Создание нового вектора
Обновление вектора
Отбрасывание вектора отбрасывает его элементы
Чтение элементов вектора
Перебор значений в векторе
Использование перечисления для хранения нескольких типов
Хранение текста в кодировке UTF-8 с помощью строк
Что такое тип String?
Создание нового экземпляра типа String
Обновление строки
Индексирование в строках
Нарезка строк
Методы перебора строк
Строки не так просты
Хранение ключей со связанными значениями в хеш-отображениях
Создание нового хеш-отображения
Хеш-отображения и владение
Доступ к значениям в хеш-отображении
Обновление хеш-отображения
Хеширующие функции
Итоги
Глава 9. Обработка ошибок
Неустранимые ошибки и макрокоманда panic!
Использование обратной трассировки при вызове panic!
Устранимые ошибки с помощью Result
Применение выражения match с разными ошибками
Краткие формы для паники в случае ошибки: unwrap и expect
Распространение ошибок
Паниковать! Или не паниковать!
Примеры, прототипный код и тесты
Случаи, когда у вас больше информации, чем у компилятора
Принципы обработки ошибок
Создание настраиваемых типов для проверки допустимости
Итоги
Глава 10. Обобщенные типы, типажи и жизненный цикл
Удаление повторов путем извлечения функции
Обобщенные типы данных
В определениях функций
В определениях структуры
В определениях перечислений
В определениях методов
Производительность кода с использованием обобщений
Типажи: определение совместного поведения
Определение типажа
Реализация типажа в типе
Реализации по умолчанию
Типажи в качестве параметров
Возвращение типов, реализующих типажи
Исправление функции largest с помощью границ типажа
Использование границ типажа для условной реализации методов
Проверка ссылок с помощью жизненных циклов
Предотвращение висячих ссылок с помощью жизненного цикла
Контролер заимствования
Обобщенные жизненные циклы в функциях
Синтаксис аннотаций жизненных циклов
Аннотации жизненных циклов в сигнатурах функций
Мышление в терминах жизненных циклов
Аннотации жизненных циклов в определениях структур
Пропуск жизненного цикла
Аннотации жизненных циклов в определениях методов
Статический жизненный цикл
Параметры обобщенного типа, границы типажа и жизненный цикл вместе
Итоги
Глава 11. Автоматизированные тесты
Как писать тесты
Анатомия функции тестирования
Проверка результатов с помощью макрокоманды assert!
Проверка равенства с помощью макрокоманд assert_eq! и assert_ne!
Добавление сообщений об ошибках для пользователя
Проверка на панику с помощью атрибута should_panic
Использование типа Result в тестах
Контроль выполнения тестов
Параллельное и последовательное выполнение тестов
Показ результатов функции
Выполнение подмножества тестов по имени
Игнорирование нескольких тестов, только если не запрошено иное
Организация тестов
Модульные тесты
Интеграционные тесты
Интеграционные тесты для двоичных упаковок
Итоги
Глава 12. Проект ввода-вывода: сборка программы командной строки
Принятие аргументов командной строки
Чтение значений аргументов
Сохранение значений аргументов в переменных
Чтение файла
Рефакторинг с целью улучшения модульности и обработки ошибок
Разделение обязанностей в двоичных проектах
Исправление обработки ошибок
Извлечение алгоритма из функции main
Разбивка кода в библиотечную упаковку
Развитие функциональности библиотеки с помощью методики разработки на основе тестов
Написание провального теста
Написание кода для успешного завершения теста
Работа с переменными среды
Написание провального теста для функции search, нечувствительной к регистру
Реализация функции search_case_insensitive
Запись сообщений об ошибках в стандартный вывод ошибок вместо стандартного вывода данных
Проверка места, куда записываются ошибки
Запись сообщения об ошибках в стандартный вывод ошибок
Итоги
Глава 13. Функциональные средства языка: итераторы и замыкания
Замыкание: анонимные функции, которые могут захватывать среду
Создание абстракции поведения с помощью замыканий
Логический вывод типа и аннотация замыкания
Ограничения в реализации структуры Cacher
Захватывание среды с помощью замыканий
Обработка серии элементов с помощью итераторов
Типаж Iterator и метод next
Методы, которые потребляют итератор
Методы, которые производят другие итераторы
Использование замыканий, которые захватывают свою среду
Создание собственных итераторов с помощью типажа Iterator
Улучшение проекта ввода-вывода
Удаление метода clone с помощью Iterator
Написание более ясного кода с помощью итераторных адаптеров
Сравнение производительности: циклы против итераторов
Итоги
Глава 14. Подробнее о Cargo и Crates.io
Собственная настройка сборок с помощью релизных профилей
Публикация упаковки для Crates.io
Внесение полезных документационных комментариев
Экспорт удобного публичного API с использованием pub
Настройка учетной записи Crates.io
Добавление метаданных в новую упаковку
Публикация в Crates.io
Публикация новой версии существующей упаковки
Удаление версий из Crates.io с помощью команды cargo yank
Рабочие пространства Cargo
Создание рабочего пространства
Создание второй упаковки в рабочем пространстве
Установка двоичных файлов из Crates.io с помощью команды cargo install
Расширение Cargo с помощью индивидуальных команд
Итоги
Глава 15. Умные указатели
Использование Box для указания на данные в куче
Использование Box для хранения данных в куче
Применение рекурсивных типов с помощью умных указателей Box
Трактовка умных указателей как обыкновенных ссылок с помощью типажа Deref
Следование по указателю к значению с помощью оператора разыменования
Использование Box в качестве ссылки
Определение собственного умного указателя
Трактовка типа как ссылки путем реализации типажа Deref
Скрытые принудительные приведения типов посредством deref с функциями и методами
Как принудительное приведение типа посредством deref взаимодействует с изменяемостью
Выполнение кода при очистке с помощью типажа Drop
Досрочное отбрасывание значения с помощью std::mem::drop
Rc — умный указатель подсчета ссылок
Применение Rc для совместного использования данных
Клонирование Rc увеличивает число ссылок
RefCell и паттерн внутренней изменяемости
Соблюдение правил заимствования во время выполнения с помощью RefCell
Внутренняя изменяемость: изменяемое заимствование неизменяемого значения
Наличие нескольких владельцев изменяемых данных путем сочетания Rc и RefCell
Циклы в переходах по ссылкам приводят к утечке памяти
Создание цикла в переходах по ссылкам
Предотвращение циклов в переходах по ссылкам: превращение Rc в Weak
Итоги
Глава 16. Конкурентность без страха
Использование потоков исполнения для одновременного выполнения кода
Создание нового потока с помощью spawn
Ожидание завершения работы всех потоков с использованием дескрипторов join
Использование замыкания move с потоками
Использование передачи сообщений для пересылки данных между потоками
Каналы и передача владения
Отправка нескольких значений и ожидание приемника
Создание нескольких производителей путем клонирования передатчика
Конкурентность совместного состояния
Использование мьютексов для обеспечения доступа к данным из одного потока за один раз
Сходства между RefCell/Rc и Mutex/Arc
Расширяемая конкурентность с типажами Send и Sync
Разрешение передавать владение между потоками с помощью Send
Разрешение доступа из нескольких потоков исполнения с помощью Sync
Реализовывать Send и Sync вручную небезопасно
Итоги
Глава 17. Средства объектно-ориентированного программирования
Характеристики объектно-ориентированных языков
Объекты содержат данные и поведение
Инкапсуляция, которая скрывает детали реализации
Наследование как система типов и как совместное использование кода
Использование типажных объектов, допускающих значения разных типов
Определение типажа для часто встречающегося поведения
Реализация типажа
Типажные объекты выполняют динамическую диспетчеризацию
Объектная безопасность необходима для типажных объектов
Реализация объектно-ориентированного паттерна проектирования
Определение поста и создание нового экземпляра в состоянии черновика
Хранение текста поста
Делаем пустой черновик
Запрос на проверку статьи изменяет ее состояние
Добавление метода approve, который изменяет поведение метода content
Компромиссы паттерна переходов между состояниями
Итоги
Глава 18. Паттерны и сопоставление
Где могут использоваться паттерны
Ветви выражения match
Условные выражения if let
Условные циклы while let
Циклы for
Инструкции let
Параметры функций
Опровержимость: возможность несовпадения паттерна
Синтаксис паттернов
Сопоставление литералов
Сопоставление именованных переменных
Несколько паттернов
Сопоставление интервалов значений с помощью синтаксиса ...
Деструктурирование для выделения значений
Игнорирование значений в паттерне
Дополнительные условия с ограничителями совпадений
Привязки @
Итоги
Глава 19. Продвинутые средства
Небезопасный Rust
Небезопасные сверхспособности
Применение оператора разыменования к сырому указателю
Вызов небезопасной функции или метода
Обращение к изменяемой статической переменной или ее модифицирование
Реализация небезопасного типажа
Когда использовать небезопасный код
Продвинутые типажи
Детализация заполнительных типов в определениях типажей с помощью связанных типов
Параметры обобщенного типа по умолчанию и перегрузка операторов
Полный синтаксис для устранения неоднозначности: вызов методов с одинаковым именем
Использование супертипажей, требующих функциональности одного типажа внутри другого типажа
Использование паттерна newtype для реализации внешних типажей во внешних типах
Продвинутые типы
Использование паттерна newtype для безопасности типов и абстракции
Создание синонимов типов с помощью псевдонимов типов
Тип never, который никогда не возвращается
Динамически изменяемые типы и типаж Sized
Продвинутые функции и замыкания
Указатели функций
Возвращающие замыкания
Макрокоманды
Разница между макрокомандами и функциями
Декларативные макрокоманды с помощью macro_rules! для общего метапрограммирования
Процедурные макрокоманды для генерирования кода из атрибутов
Как написать настраиваемую макрокоманду derive
Макрокоманды, подобные атрибутам
Макрокоманды, подобные функциям
Итоги
Глава 20. Финальный проект: сборка многопоточного сервера
Сборка однопоточного сервера
Прослушивание TCP-соединения
Чтение запроса
HTTP-запрос
Написание ответа
Возвращение реального HTML
Проверка запроса и выборочный ответ
Небольшой рефакторинг
Превращение однопоточного сервера в многопоточный
Моделирование медленного запроса в текущей реализации сервера
Повышение пропускной способности с помощью пула потоков исполнения
Корректное отключение и очистка
Реализация типажа Drop для ThreadPool
Подача потокам сигнала об остановке прослушивания заданий
Итоги
Приложение А.
Ключевые слова
Ключевые слова, употребляемые в настоящее время
Ключевые слова, зарезервированные для использования в будущем
Сырые идентификаторы
Приложение Б.
Операторы и символы
Операторы
Неоператорные символы
Приложение В
Генерируемые типажи
Debug для вывода рабочей информации
PartialEq и Eq для сравнений равенств
PartialOrd и Ord для сравнений порядка
Clone и Copy для дублирования значений
Хеш для отображения значения в значение фиксированного размера
Default для значений по умолчанию
Приложение Г
Полезные инструменты разработки
Автоматическое форматирование с помощью rustfmt
Исправляйте код с помощью rustfix
Статический анализ кода с помощью Clippy
Интеграция с IDE с помощью языкового сервера Rust Language Server
Приложение Д
Редакции