The Rust Programming Language
This repository contains the source of «The Rust Programming Language» book.
The book is available in dead-tree form from No Starch Press.
You can also read the book for free online. Please see the book as shipped with
the latest stable, beta, or nightly Rust releases. Be aware that issues
in those versions may have been fixed in this repository already, as those
releases are updated less frequently.
See the releases to download just the code of all the code listings that appear in the book.
Requirements
Building the book requires mdBook, ideally the same version that
rust-lang/rust uses in this file. To get it:
$ cargo install mdbook --version <version_num>
Building
To build the book, type:
The output will be in the book
subdirectory. To check it out, open it in
your web browser.
Firefox:
$ firefox book/index.html # Linux $ open -a "Firefox" book/index.html # OS X $ Start-Process "firefox.exe" .\book\index.html # Windows (PowerShell) $ start firefox.exe .\book\index.html # Windows (Cmd)
Chrome:
$ google-chrome book/index.html # Linux $ open -a "Google Chrome" book/index.html # OS X $ Start-Process "chrome.exe" .\book\index.html # Windows (PowerShell) $ start chrome.exe .\book\index.html # Windows (Cmd)
To run the tests:
Contributing
We’d love your help! Please see CONTRIBUTING.md to learn about the
kinds of contributions we’re looking for.
Because the book is printed, and because we want
to keep the online version of the book close to the print version when
possible, it may take longer than you’re used to for us to address your issue
or pull request.
So far, we’ve been doing a larger revision to coincide with Rust
Editions. Between those larger
revisions, we will only be correcting errors. If your issue or pull request
isn’t strictly fixing an error, it might sit until the next time that we’re
working on a large revision: expect on the order of months or years. Thank you
for your patience!
Translations
We’d love help translating the book! See the Translations label to join in
efforts that are currently in progress. Open a new issue to start working on
a new language! We’re waiting on mdbook support for multiple languages
before we merge any in, but feel free to start!
Spellchecking
To scan source files for spelling errors, you can use the spellcheck.sh
script available in the ci
directory. It needs a dictionary of valid words,
which is provided in ci/dictionary.txt
. If the script produces a false
positive (say, you used word BTreeMap
which the script considers invalid),
you need to add this word to ci/dictionary.txt
(keep the sorted order for
consistency).
The Rust compiler is written in Rust, but I’m not sure what that has to do with the existence of beta or nightly, or why their existence would refute anything. Nightly exists so people can try new features and changes as they are being developed.
You can easily notice similarities between Rust and C++ syntax, but Rust offers a higher level of memory safety without using a garbage collector. Not for the first time, Rust has been named the most loved language—it gained more than 86% of developers’ votes.
Rust incorporates a memory ownership model enforced at a compile time. Since this model involves zero runtime overhead, programs written in Rust are not only memory-safe but also fast, leading to performance comparable to C and C++.
Привет, Хаброжители! Официальный гайд по языку программирования Rust поможет вам создавать более быстрое и надежное программное обеспечение. Высокоуровневая эргономика и низкоуровневое управление часто противоречат друг другу, но Rust бросает вызов этому конфликту.
Авторы книги входят в команду разработчиков языка, а значит, вы получите всю информацию из первых рук — от установки языка до создания надежных и масштабируемых программ. От создания функций, выбора типов данных и привязки переменных вы перейдете к более сложным концепциям:
- Владение и заимствование, жизненный цикл и типажи.
- Гарантированная безопасность программ.
- Тестирование, обработка ошибок и эффективный рефакторинг.
- Обобщения, умные указатели, многопоточность, типажные объекты и сопоставления.
- Работа со встроенным менеджером пакетов Cargo для создания, тестирования, документирования кода и управления зависимостями.
- Продвинутые средства работы с Unsafe Rust.
Вы найдете множество примеров кода, а также три главы, посвященные созданию полноценных проектов для закрепления знаний: игры-угадайки, создание инструмента командной строки и многопоточного сервера.
Для кого эта книга
Мы предполагаем, что вы писали код на другом языке программирования, но не делаем никаких допущений относительно того, на каком именно. Мы постарались сделать этот материал доступным для тех, кто имеет широкий спектр навыков программирования. Мы не будем тратить время на разговоры о том, что такое программирование. Если вы в программировании абсолютный новичок, то для начала прочтите введение в программирование.
Как пользоваться этой книгой
В общем-то, авторы этой книги исходят из того, что вы читаете ее последовательно, от начала до конца. Последующие главы строятся на понятиях предыдущих глав, и в начальных главах мы можем не углубляться в детали по конкретной теме; обычно мы возвращаемся к этой теме в дальнейшем.
В этой книге вы найдете два типа глав: концептуальные и проектные. В концептуальных главах вы будете усваивать тот или иной аспект языка. Мы вместе будем создавать небольшие программы, применяя то, что вы уже усвоили. Главы 2, 12 и 20 посвящены разработке проектов, остальные главы — концептуальные.
В главе 1 рассказано, как установить Rust, написать программу «Hello, World!» и использовать пакетный менеджер и инструмент Cargo. Глава 2 представляет собой практическое введение в язык Rust. Здесь мы рассмотрим понятия с точки зрения высокоуровневого языка, а в последующих главах приведем дополнительные подробности. Если вы хотите сразу же приступить к практике, то сможете это сделать. Можно даже пропустить главу 3, в которой рассматриваются средства языка Rust, аналогичные средствам других языков программирования, сразу перейти к главе 4 и узнать о системе владения в Rust. Но если вы дотошны и предпочитаете разбирать каждую деталь, прежде чем переходить к следующей, то можете пропустить главу 2, перейти к главе 3, а затем вернуться к главе 2, когда захотите поработать над проектом. Так вы сможете применить знания, которые освоили.
В главе 5 обсуждаются структуры и методы, а в главе 6 рассматриваются перечисления, выражения match и конструкция управления потоком if let. Вы будете использовать структуры и перечисления для создания в языке Rust настраиваемых типов.
В главе 7 вы узнаете о системе модулей и правилах конфиденциальности для выстраивания организационной структуры вашего кода и его публичном интерфейсе программирования приложений (API). В главе 8 обсуждаются некоторые часто встречающиеся структуры сбора данных, обеспечиваемые стандартной библиотекой, такие как векторы, строки и хеш-отображения. В главе 9 изучаются философия и методы обработки ошибок.
В главе 10 мы погрузимся в обобщения, типажи и жизненные циклы, которые дают вам возможность определять код, применимый к нескольким типам. Глава 11 полностью посвящена тестированию, которое даже несмотря на гарантии безопасности языка Rust является необходимым для обеспечения правильной логики программы. В главе 12 мы построим собственную реализацию подмножества функциональности инструмента командной строки grep, которая ищет текст внутри файлов. Для этого мы воспользуемся многими понятиями, которые обсуждаются в предыдущих главах.
В главе 13 рассматриваются замыкания и итераторы — средства, которые восходят к функциональным языкам программирования. В главе 14 мы изучим Cargo подробнее и расскажем о лучших практических приемах обмена библиотеками с другими разработчиками. В главе 15 обсуждаются умные указатели, которые обеспечивает стандартная библиотека, и типажи, которые гарантируют их функциональность.
В главе 16 мы рассмотрим разные модели конкурентного программирования и поговорим о том, как Rust помогает вам безбоязненно программировать в множестве потоков исполнения. Глава 17 обращается к сопоставлению идиом Rust с принципами объектно-ориентированного программирования, с которыми вы, возможно, знакомы.
Глава 18 представляет собой справочный материал о паттернах и сопоставлении с паттернами, которые являются мощными способами выражения идей во всех программах на языке Rust. Глава 19 содержит ряд дополнительных тем, представляющих интерес, включая небезопасный код Rust, макрокоманды и другие сведения о типажах, типах, функциях и замыканиях.
В главе 20 мы осуществим проект, в котором выполним реализацию низкоуровневого многопоточного сервера!
Наконец, несколько приложений в конце книги содержат полезную информацию о языке в справочном формате. В приложении А приводятся ключевые слова языка Rust, в приложении Б рассказывается об операторах и символах языка Rust, в приложении В рассматриваются генерируемые типажи, предусмотренные стандартной библиотекой, в приложении Г приводятся некоторые полезные инструменты разработчика, а в приложении Д даются пояснения по поводу редакций языка Rust.
Просто невозможно прочитать эту книгу неправильно: если вы хотите пропустить что-то, пропускайте! В случае если вы почувствуете какую-то путаницу, то, возможно, вам придется вернуться к предыдущим главам. Короче, делайте все, что вам подходит.
Важная часть процесса усвоения языка Rust — научиться читать сообщения об ошибках, выводимые на экран компилятором: они будут направлять вас к рабочему коду. В связи с этим мы приведем много примеров, которые не компилируются вместе с сообщением об ошибке, которое компилятор покажет вам в каждой ситуации. Знайте, что если вы введете и запустите выполнение случайного примера, то он может не скомпилироваться! Обязательно прочтите окружающий текст, чтобы увидеть, что пример, который вы пытаетесь выполнить, является неизбежно ошибочным. В большинстве ситуаций мы будем вести вас к правильной версии любого кода, который не компилируется.
Где могут использоваться паттерны
В Rust паттерны много где появляются, и вы часто их использовали, даже не осознавая этого! В данном разделе рассматриваются ситуации, в которых паттерны допустимы.
Ветви выражения match
Как обсуждалось в главе 6, мы используем паттерны в ветвях выражений match. Формально выражения match определяются как ключевое слово match, затем значение для сопоставления и один или несколько ветвей совпадения, состоящих из паттерна и выполняемого выражения, если значение совпадает с паттерном этой ветви, например:
match ЗНАЧЕНИЕ {
ПАТТЕРН => ВЫРАЖЕНИЕ,
ПАТТЕРН => ВЫРАЖЕНИЕ,
ПАТТЕРН => ВЫРАЖЕНИЕ,
}
Одно из требований к выражениям match состоит в том, что они должны быть исчерпывающими в том смысле, что в match должны быть учтены все возможные значения. Чтобы вы учитывали все возможные варианты, нужно иметь всеохватывающий паттерн в последней ветви: например, имя переменной, совпадающее с любым значением, всегда будет срабатывать и, таким образом, охватывать все оставшиеся случаи.
Особый паттерн _ будет совпадать с чем угодно, но он не привязывается к переменной и поэтому часто используется в последнем рукаве совпадения. Паттерн _ бывает полезен, например, если вы хотите проигнорировать любое неуказанное значение. Мы рассмотрим паттерн _ подробнее в разделе «Игнорирование значений в паттерне».
Условные выражения if let
В главе 6 мы обсуждали выражения if let главным образом как более краткий способ написания эквивалента выражения match, который совпадает только с одним случаем. Как вариант if let может иметь соответствующий else, содержащий выполняемый код, если паттерн в выражении if let не совпадает.
Листинг 18.1 показывает, что также существует возможность смешивать и сочетать выражения if let, else if и else if let. Благодаря этому мы получаем больше гибкости, чем при использовании выражения match, в котором можно выразить только одно сравниваемое с паттернами значение. Кроме того, условия в серии выражений if let, else if и else if let не обязательно должны относиться друг к другу.
Код в листинге 18.1 показывает серию проверок на несколько условий, которые решают, каким должен быть фоновый цвет. В этом примере мы создали переменные с жестко заданными значениями, которые реальная программа могла бы получить из данных, вводимых пользователем.
Листинг 18.1. Смешивание выражений if let, else if, else if let и else
src/main.rs
fn main() {
let favorite_color: Option<&str> = None;
let is_tuesday = false;
let age: Result<u8, _> = "34".parse();
(1) if let Some(color) = favorite_color {
(2) println!("Используя ваш любимый цвет, {}, в качестве фона", color);
(3) } else if is_tuesday {
(4) println!("Вторник - зеленый день!");
(5) } else if let Ok(age) = age {
(6) if age > 30 {
(7) println!("Использование фиолетового цвета в качестве фона");
} else {
(8) println!("Использование оранжевого цвета в качестве фона");
}
(9) } else {
(10) println!("Использование синего цвета в качестве фона");
}
}
Если пользователь указывает любимый цвет (1), то это фоновый цвет (2). Если сегодня — вторник (3), то фоновый цвет — зеленый (4). Если пользователь указывает свой возраст в качестве строки и мы можем успешно разобрать ее как число (5), то цвет будет либо фиолетовым (7), либо оранжевым (8) в зависимости от значения числа (6). Если ни одно из этих условий не применимо (9), то фоновый цвет — синий (10).
Эта условная структура позволяет поддерживать сложные требования. С жестко закодированными значениями, которые здесь есть, этот пример будет выводить
Использование фиолетового цвета в качестве фона.
Вы видите, что выражение if let может также вводить затененные переменные таким же образом, как и рукава выражения match: строка кода if let Ok(age) = age (5) вводит новую затененную переменную age, содержащую значение внутри варианта Ok. Это означает, что нужно поместить условие if age > 30 в этот блок (6): мы не можем совместить эти два условия в выражении if let Ok (age) = age && age > 30. Затененная переменная age, которую мы хотим сравнить с 30, будет недействительна до тех пор, пока новая область видимости не начнется с фигурной скобки.
Недостатком использования выражений if let является то, что компилятор не проверяет исчерпываемость, в то время как с выражениями match он это делает. Если бы мы пропустили последний блок else (9) и, следовательно, обработку некоторых случаев, то компилятор не предупредил бы нас о возможной логической ошибке.
Условные циклы while let
Похожий по конструкции с выражением if let условный цикл while let позволяет циклу while работать до тех пор, пока паттерн совпадает. Пример в листинге 18.2 показывает цикл while let, который использует вектор в качестве стека и выводит значения в векторе в порядке, обратном тому, в котором они были добавлены.
Листинг 18.2. Использование цикла while let для печати значений, пока метод stack.pop() возвращает Some
let mut stack = Vec::new();
stack.push(1);
stack.push(2);
stack.push(3);
while let Some(top) = stack.pop() {
println!("{}", top);
}
В этом примере выводятся 3, 2 и затем 1. Метод pop берет последний элемент из вектора и возвращает Some(value). Если вектор пуст, то pop возвращает None. Цикл while продолжает выполнение кода в своем блоке до тех пор, пока pop возвращает Some. Когда pop возвращает None, цикл останавливается. Мы можем использовать условный цикл while let, чтобы удалить каждый элемент из стека.
Циклы for
В главе 3 мы упоминали, что цикл for — это наиболее распространенная циклическая конструкция в коде на языке Rust, но мы еще не обсуждали паттерн, который берет for. В цикле for паттерном является значение, следующее непосредственно за ключевым словом for, поэтому в for x in y паттерном является x.
Листинг 18.3 показывает использование паттерна в цикле for для деструктурирования, или разложения, кортежа в рамках for.
Листинг 18.3. Использование паттерна в цикле for для деструктурирования кортежа
let v = vec!['a', 'b', 'c'];
for (index, value) in v.iter().enumerate() {
println!("{} находится в индексе {}", value, index);
}
Код из листинга 18.3 выводит следующее:
а находится в индексе 0
b находится в индексе 1
с находится в индексе 2
Мы используем метод enumerate, чтобы переделать итератор для порождения значения и индекса этого значения в итераторе, помещенных в кортеж. Первый вызов метода enumerate порождает кортеж (0, ‘a’). Когда это значение сочетается с паттерном (index, value), то index равен 0, а value равно ‘a’, выводится первая строка данных.
Инструкции let
До этой главы мы прямо обсуждали использование паттернов только с выражениями match и if let, но на самом деле мы использовали паттерны и в других местах, в том числе в инструкциях let. Рассмотрим простую передачу значения переменной с помощью let:
let x = 5;
На протяжении всей книги мы сотни раз использовали инструкции let подобного рода, и хотя вы, возможно, не осознавали этого, вы использовали паттерны! В более формальном плане инструкция let выглядит так:
let ПАТТЕРН = ВЫРАЖЕНИЕ;
В таких инструкциях, как let x = 5;, с именем переменной в слоте ПАТТЕРН, имя переменной — это всего лишь простая форма паттерна. Rust сравнивает выражение с паттерном и назначает любые имена, которые он находит. Поэтому в примере let x = 5; паттерном является x, который означает «связать то, что совпадает здесь, с переменной x». Поскольку имя x представляет весь паттерн, то этот паттерн фактически означает «связать все с переменной x, каким бы ни было значение».
Чтобы четче увидеть сопоставление с паттерном инструкции let, рассмотрим листинг 18.4, который использует паттерн с let для деструктурирования кортежа.
Листинг 18.4. Использование паттерна для деструктурирования кортежа и создания сразу трех переменных
let (x, y, z) = (1, 2, 3);
Здесь мы сопоставляем кортеж с паттерном. Rust сравнивает (1, 2, 3) с (x, y, z) и видит, что это значение совпадает с паттерном, поэтому Rust связывает 1 с x, 2 с y и 3 с z. Можно думать об этом кортежном паттерне как о вложении в него трех отдельных паттернов переменных.
Если число элементов в паттерне не совпадает с числом элементов в кортеже, то совокупный тип не будет совпадать и мы получим ошибку компилятора. Например, листинг 18.5 показывает попытку деструктурирования кортежа из трех элементов в две переменные, которая не будет работать.
Листинг 18.5. Неправильное построение паттерна, переменные которого не совпадают с числом элементов в кортеже
let (x, y) = (1, 2, 3);
Попытка компиляции этого кода приводит к ошибке типа:
error[E0308]: mismatched types
--> src/main.rs:2:9
|
2 | let (x, y) = (1, 2, 3);
| ^^^^^^ expected a tuple with 3 elements, found one with 2 elements
|
= note: expected type `({integer}, {integer}, {integer})`
found type `(_, _)`
Если бы мы хотели проигнорировать одно или несколько значений в кортеже, то могли бы использовать _ или .., как вы увидите в разделе «Игнорирование значений в паттерне». Если проблема состоит в том, что в паттерне слишком много переменных, то нужно сделать так, чтобы типы совпадали, удалив переменные, чтобы число переменных равнялось числу элементов в кортеже.
Параметры функций
Параметры функций также могут быть паттернами. Код в листинге 18.6, объявляющий функцию foo, которая берет один параметр x типа i32, теперь вам знаком.
Листинг 18.6. Сигнатура функции использует паттерны в параметрах
fn foo(x: i32) {
// здесь будет код
}
Часть x — это паттерн! Как и в случае с let, мы можем сопоставить кортеж в аргументах функции с паттерном. Листинг 18.7 разбивает значения в кортеже в момент, когда мы передаем его внутрь функции.
Листинг 18.7. Функция с параметрами, которые деструктурируют кортеж
src/main.rs
fn print_coordinates(&(x, y): &(i32, i32)) {
println!("Текущее местоположение: ({}, {})", x, y);
}
fn main() {
let point = (3, 5);
print_coordinates(&point);
}
Этот код выводит
Текущее местоположение: (3, 5)
Значения &(3, 5) совпадают с паттерном &(x, y), поэтому x равно 3, а y — 5.
Кроме того, мы можем использовать паттерны в списках параметров замыкания таким же образом, как и в списках параметров функций, поскольку замыкания похожи на функции, как описано в главе 13.
Вы уже увидели несколько способов использования паттернов, но они не работают одинаково всюду, где можно их применить. В некоторых ситуациях эти паттерны должны быть неопровержимы, в других — они могут быть опровержимы. Далее мы обсудим эти два понятия.
Опровержимость: возможность несовпадения паттерна
Паттерны бывают двух видов: опровержимые и неопровержимые. Паттерны, которые будут совпадать с любым возможным переданным значением, неопровержимые. Примером является x в инструкции let x = 5;, потому что x совпадает абсолютно со всем и, следовательно, не может не совпасть. Паттерны, которые не совпадают с некоторыми возможными значениями, являются опровержимыми. Примером служит Some(x) в выражении if let Some(x) = a_value, потому что, если значение в переменной a_value равно None, а не Some, то паттерн Some(x) не совпадет.
Параметры функций, инструкции let и циклы for могут принимать только неопровержимые паттерны, поскольку программа не сможет делать ничего значимого, когда значения не совпадают. Выражения if let и while let принимают только опровержимые паттерны, поскольку по определению они предназначены для обработки возможной ошибки: функциональность условного выражения заключается в его способности выполнять разные действия в зависимости от успеха или провала.
В целом вам не следует беспокоиться о различии между опровержимыми и неопровержимыми паттернами. Однако вам все-таки нужно знать о понятии опровержимости, чтобы реагировать при виде его в сообщении об ошибке. В этих случаях вам потребуется изменить либо паттерн, либо конструкцию, с которой вы используете паттерн, в зависимости от предполагаемого поведения кода.
Давайте рассмотрим, что происходит, когда мы пытаемся использовать опровержимый паттерн в месте, где Rust требует неопровержимый паттерн, и наоборот. Листинг 18.8 показывает инструкцию let, но для паттерна мы задали Some(x), опровержимый паттерн. Как и следовало ожидать, этот код не компилируется.
Листинг 18.8. Попытка использовать опровержимый паттерн с let
let Some(x) = some_option_value;
Если бы значение some_option_value было равно None, то оно не совпало бы с паттерном Some(x), то есть паттерн является опровержимым. Однако инструкция let может принимать только неопровержимый паттерн, поскольку код не может сделать ничего допустимого со значением None. Во время компиляции язык Rust будет жаловаться, что мы пытались использовать опровержимый паттерн там, где требуется неопровержимый паттерн:
error[E0005]: refutable pattern in local binding: `None` not covered
-->
|
3 | let Some(x) = some_option_value;
| ^^^^^^^ pattern `None` not covered
Поскольку мы не охватили (и не могли охватить!) каждое допустимое значение с паттерном Some(x), Rust по праву выдает ошибку компилятора.
Для устранения проблемы, когда у нас опровержимый паттерн вместо неопровержимого, мы можем изменить код, использующий паттерн: вместо let можно применить if let. Тогда, если паттерн не совпадает, то код в фигурных скобках будет пропущен и работа продолжится корректно. Листинг 18.9 показывает, как исправить код из листинга 18.8.
Листинг 18.9. Использование выражения if let и блока с опровержимыми паттернами вместо let
if let Some(x) = some_option_value {
println!("{}", x);
}
Код готов! Это абсолютно правильный код, хотя он означает, что мы не можем использовать неопровержимый паттерн без ошибки. Если мы дадим выражению if let паттерн, который всегда будет совпадать, например x, как показано в листинге 18.10, то он компилироваться не будет.
Листинг 18.10. Попытка использовать неопровержимый паттерн с выражением if let
if let x = 5 {
println!("{}", x);
};
Компилятор жалуется, что использовать выражение if let с неопровержимым паттерном не имеет смысла:
error[E0162]: irrefutable if-let pattern
--> <anon>:2:8
|
2 | if let x = 5 {
| ^ irrefutable pattern
По этой причине рукава выражения match должны использовать опровержимые паттерны, за исключением последнего рукава, который должен сопоставлять любые оставшиеся значения с неопровержимым паттерном. Rust позволяет использовать неопровержимый паттерн в выражении match только с одним рукавом, но этот синтаксис не особо полезен, и его можно заменить более простой инструкцией let.
Теперь, когда вы знаете, где используются паттерны и чем отличаются опровержимые и неопровержимые паттерны, давайте познакомимся с синтаксисом, который мы можем использовать для создания паттернов.
Об авторах
Стив Клабник возглавляет команду по документированию Rust и является одним из ключевых разработчиков языка. Часто выступает с лекциям и пишет много открытого исходного кода. Ранее работал над такими проектами, как Ruby и Ruby on Rails.
Кэрол Николс является членом команды разработчиков Rust Core и соучредителем Integer 32, LLC, первой в мире консалтинговой компании по разработке ПО, ориентированной на Rust. Николс является организатором конференции «Ржавый пояс» (Rust Belt) по языку Rust.
» Более подробно с книгой можно ознакомиться на сайте издательства
» Оглавление
» Отрывок
Для Хаброжителей скидка 25% по купону — Rust
По факту оплаты бумажной версии книги на e-mail высылается электронная книга.
by Steve Klabnik and Carol Nichols, with contributions from the Rust Community
This version of the text assumes you’re using Rust 1.41.0 or later with edition="2018"
in Cargo.toml of all projects to use Rust 2018 Edition idioms. See the “Installation” section of Chapter 1 to install or update Rust, and see the new Appendix E for information on editions.
The 2018 Edition of the Rust language includes a number of improvements that make Rust more ergonomic and easier to learn. This iteration of the book contains a number of changes to reflect those improvements:
- Chapter 7, “Managing Growing Projects with Packages, Crates, and Modules,” has been mostly rewritten. The module system and the way paths work in the 2018 Edition were made more consistent.
- Chapter 10 has new sections titled “Traits as Parameters” and “Returning Types that Implement Traits” that explain the new
impl Trait
syntax. - Chapter 11 has a new section titled “Using
Result<T, E>
in Tests” that shows how to write tests that use the?
operator. - The “Advanced Lifetimes” section in Chapter 19 was removed because compiler improvements have made the constructs in that section even rarer.
- The previous Appendix D, “Macros,” has been expanded to include procedural macros and was moved to the “Macros” section in Chapter 19.
- Appendix A, “Keywords,” also explains the new raw identifiers feature that enables code written in the 2015 Edition and the 2018 Edition to interoperate.
- Appendix D is now titled “Useful Development Tools” and covers recently released tools that help you write Rust code.
- We fixed a number of small errors and imprecise wording throughout the book. Thank you to the readers who reported them!
Note that any code in earlier iterations of The Rust Programming Language that compiled will continue to compile without edition="2018"
in the project’s Cargo.toml, even as you update the Rust compiler version you’re using. That’s Rust’s backward compatibility guarantees at work!
The HTML format is available online at https://doc.rust-lang.org/stable/book/ and offline with installations of Rust made with rustup
; run rustup docs --book
to open.
This text is available in paperback and ebook format from No Starch Press.
Последнее обновление: 28.08.2022
-
Глава 1. Введение в язык Rust
-
Общий обзор языка программирования Rust. Установка
-
Первая программа
-
-
Глава 2. Основы Rust
-
Структура программы
-
Переменные
-
Типы данных
-
Арифметические операции
-
Поразрядные операции
-
Условные выражения
-
Конструкция if..else
-
Конструкция match
-
Циклы
-
Функции
-
Параметры функции
-
Возвращение значения из функции
-
Константы
-
Анонимные функции
-
Замыкания
-
Тип функции
-
Функция как параметр и результат другой функции
-
-
Глава 3. Составные типы данных
-
Кортежи
-
Массивы
-
Структуры
-
Структуры-кортежи
-
Перечисления Enum
-
Последовательность Range
-
Паттерны и конструкция match
-
Паттерны и конструкция if let
-
-
Глава 4. Ссылки и Ownership
-
Контекст/область видимости
-
Устройство памяти в Rust. Стек и куча
-
Ownership
-
Ссылки
-
Изменяемые ссылки
-
Slice
-
-
Глава 5. Объектно-ориентированное программирование
-
Методы
-
Ассоциированные функции
-
Trait
-
Trait как параметр и результат функции
-
Generics. Обобщенные типы
-
Generics. Обобщенные функции и методы
-
Trait bound
-
-
Глава 6. Время жизни ссылки
-
Аннотации и время жизни ссылки
-
Аннотации ссылок в функциях
-
Аннотации ссылок в структурах
-
Аннотации ссылок в определениях методов
-
Статическое время жизни
-
-
Глава 7. Коллекции
-
Вектор
-
String
-
HashMap
-
-
Глава 8. Модули
-
Определение модулей. Приватность и публичность
-
Вложенные модули и ключевое слово super
-
Оператор use и подключение модулей
-
Определение модуля во внешнем файле
-
-
Глава 9. Обработка ошибок
-
Макрос panic!
-
Тип Result
-
Методы unwrap и expect типа Result
-
Обработка нескольких типов ошибок
-
Оператор ?
-
-
Глава 10. Cargo
-
Создание проекта с помощью Cargo
-
Загрузка и использование внешних зависимостей
-
-
Глава 11. Ввод и вывод
-
Ввод с клавиатуры
-
-
Глава 12. Unsafe-контекст
-
Указатели
-
- Глава 1. Введение в язык Rust
- Общий обзор языка программирования Rust. Установка
- Первая программа
- Глава 2. Основы Rust
- Структура программы
- Переменные
- Типы данных
- Арифметические операции
- Поразрядные операции
- Условные выражения
- Конструкция if..else
- Конструкция match
- Циклы
- Функции
- Параметры функции
- Возвращение значения из функции
- Константы
- Анонимные функции
- Замыкания
- Тип функции
- Функция как параметр и результат другой функции
- Глава 3. Составные типы данных
- Кортежи
- Массивы
- Структуры
- Структуры-кортежи
- Перечисления Enum
- Последовательность Range
- Паттерны и конструкция match
- Паттерны и конструкция if let
- Глава 4. Ссылки и Ownership
- Контекст/область видимости
- Устройство памяти в Rust. Стек и куча
- Ownership
- Ссылки
- Изменяемые ссылки
- Slice
- Глава 5. Объектно-ориентированное программирование
- Методы
- Ассоциированные функции
- Trait
- Trait как параметр и результат функции
- Generics. Обобщенные типы
- Generics. Обобщенные функции и методы
- Trait bound
- Глава 6. Время жизни ссылки
- Аннотации и время жизни ссылки
- Аннотации ссылок в функциях
- Аннотации ссылок в структурах
- Аннотации ссылок в определениях методов
- Статическое время жизни
- Глава 7. Коллекции
- Вектор
- String
- HashMap
- Глава 8. Модули
- Определение модулей. Приватность и публичность
- Вложенные модули и ключевое слово super
- Оператор use и подключение модулей
- Определение модуля во внешнем файле
- Глава 9. Обработка ошибок
- Макрос panic!
- Тип Result
- Методы unwrap и expect типа Result
- Обработка нескольких типов ошибок
- Оператор ?
- Глава 10. Cargo
- Создание проекта с помощью Cargo
- Загрузка и использование внешних зависимостей
- Глава 11. Ввод и вывод
- Ввод с клавиатуры
- Глава 12. Unsafe-контекст
- Указатели