Официальное руководство rust

The Rust Programming Language

Build Status

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" .bookindex.html # Windows (PowerShell)
$ start firefox.exe .bookindex.html           # Windows (Cmd)

Chrome:

$ google-chrome book/index.html                 # Linux
$ open -a "Google Chrome" book/index.html       # OS X
$ Start-Process "chrome.exe" .bookindex.html  # Windows (PowerShell)
$ start chrome.exe .bookindex.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).

Introduction

Эта книга является основным справочником по языку программирования «Ржавчина».В ней представлены три вида материала:

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

Предупреждение: эта книга неполная. Документирование всего требует времени. См. Проблемы на GitHub, чтобы узнать о том, что не описано в этой книге.

Rust releases

Rust выпускает новый языковой выпуск каждые шесть недель. Первым стабильным выпуском языка был Rust 1.0.0, за ним последовал Rust 1.1.0 и так далее. Инструменты ( rustc , cargo и т. Д.) И документация ( стандартная библиотека , эта книга и т. Д.) Выпускаются вместе с языковым выпуском.

Последний выпуск этой книги, соответствующий последней версии Rust, всегда можно найти по адресу https://doc.rust-lang.org/reference/ . Предыдущие версии можно найти, добавив версию Rust перед «справочным» каталогом. Например, Справочник по Rust 1.49.0 находится по адресу https://doc.rust-lang.org/1.49.0/reference/ .

Чем не является ссылка

Эта книга не является введением в язык. Предполагается предварительное знакомство с языком. Доступна отдельная книга, которая поможет вам ознакомиться с такими предысториями.

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

Точно так же эта книга обычно не документирует особенности rustc как инструмента или Cargo. rustc есть своя собственная книга . У Cargo есть книга, в которой есть ссылка . Есть несколько страниц, таких как linkage, которые все еще описывают, как работает rustc .

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

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

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

Как использовать эту книгу

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

Существует два основных способа прочтения этого документа.

Первый — ответить на конкретный вопрос. Если вы знаете, какая глава отвечает на этот вопрос, вы можете перейти к этой главе в оглавлении. В противном случае вы можете нажать s или щелкнуть увеличительное стекло на верхней панели для поиска ключевых слов, связанных с вашим вопросом. Например, предположим, что вы хотите знать, когда временное значение, созданное в инструкции let, удаляется. Если вы еще не знали, что время жизни временных файлов определено в главе о выражениях , вы можете выполнить поиск по запросу «временный let», и первый результат поиска приведет вас к этому разделу.

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

Тем не менее,нет никакого неправильного способа прочитать эту книгу.Читайте ее,как бы вы ни чувствовали,что она вам поможет.

Conventions

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

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

    Примерный термин — это пример определяемого термина.

  • Различия в языке, для которого составлен ящик, указаны в кавычках, которые начинаются со слов «Различия в редакциях:», выделенных жирным шрифтом .

    Различия между редакциями : в редакции 2015 года действует этот синтаксис, который запрещен в редакции 2018 года.

  • Примечания, которые содержат полезную информацию о состоянии книги или указывают на полезную, но в основном выходящую за рамки, информацию заключают в кавычки, которые начинаются со слова «Примечание:» жирным шрифтом .

    Примечание . Это пример заметки.

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

    Внимание:Это пример предупреждения.

  • Фрагменты кода, встроенные в текст, находятся внутри тегов <code> .

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

    fn main() {
        println!("This is a code example");
    }
    

    Все примеры написаны для последнего издания,если не указано иное.

  • Грамматика и лексическая структура заключены в кавычки, а в первой строке жирным надстрочным шрифтом выделены либо «Lexer», либо «Syntax» .

    Syntax
    ExampleGrammar:
    ~Expression
    | boxExpression

    См. Обозначения для более подробной информации.

Contributing

Мы приветствуем всевозможный вклад.

Вы можете внести свой вклад в эту книгу, открыв вопрос или отправив запрос на перенос в репозиторий Rust Reference . Если эта книга не отвечает на ваш вопрос, и вы думаете, что ответ входит в его рамки, пожалуйста, не стесняйтесь сообщать о проблеме или спрашивать о ней в потоке t-lang/doc на Zulip . Знание того, для чего люди используют эту книгу чаще всего, помогает направить наше внимание на то, чтобы сделать эти разделы как можно лучше. Мы также хотим, чтобы ссылка была как можно более нормативной, поэтому, если вы видите что-то неправильное или ненормативное, но специально не упомянутое, также сообщите о проблеме .


Rust

1.65

  • Glossary

    Абстрактное синтаксическое дерево»,или «AST»,-это промежуточное представление структурной программы при ее компиляции компилятором.

  • Identifiers

    Лексер:IDENTIFIER_OR_KEYWORD XID_Start XID_Continue*RAW_IDENTIFIER IDENTIFIER_OR_KEYWORD Except crate,self,super,NON_KEYWORD_IDENTIFIER IDENTIFIER_OR_KEYWORD

  • Influences

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

  • Inline assembly

    Поддержка встроенной сборки обеспечивается макросами asm! и global_asm!

image Привет, Хаброжители! Официальный гайд по языку программирования 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 высылается электронная книга.

Последнее обновление: 28.08.2022

  1. Глава 1. Введение в язык Rust

    1. Общий обзор языка программирования Rust. Установка

    2. Первая программа

  2. Глава 2. Основы Rust

    1. Структура программы

    2. Переменные

    3. Типы данных

    4. Арифметические операции

    5. Поразрядные операции

    6. Условные выражения

    7. Конструкция if..else

    8. Конструкция match

    9. Циклы

    10. Функции

    11. Параметры функции

    12. Возвращение значения из функции

    13. Константы

    14. Анонимные функции

    15. Замыкания

    16. Тип функции

    17. Функция как параметр и результат другой функции

  3. Глава 3. Составные типы данных

    1. Кортежи

    2. Массивы

    3. Структуры

    4. Структуры-кортежи

    5. Перечисления Enum

    6. Последовательность Range

    7. Паттерны и конструкция match

    8. Паттерны и конструкция if let

  4. Глава 4. Ссылки и Ownership

    1. Контекст/область видимости

    2. Устройство памяти в Rust. Стек и куча

    3. Ownership

    4. Ссылки

    5. Изменяемые ссылки

    6. Slice

  5. Глава 5. Объектно-ориентированное программирование

    1. Методы

    2. Ассоциированные функции

    3. Trait

    4. Trait как параметр и результат функции

    5. Generics. Обобщенные типы

    6. Generics. Обобщенные функции и методы

    7. Trait bound

  6. Глава 6. Время жизни ссылки

    1. Аннотации и время жизни ссылки

    2. Аннотации ссылок в функциях

    3. Аннотации ссылок в структурах

    4. Аннотации ссылок в определениях методов

    5. Статическое время жизни

  7. Глава 7. Коллекции

    1. Вектор

    2. String

    3. HashMap

  8. Глава 8. Модули

    1. Определение модулей. Приватность и публичность

    2. Вложенные модули и ключевое слово super

    3. Оператор use и подключение модулей

    4. Определение модуля во внешнем файле

  9. Глава 9. Обработка ошибок

    1. Макрос panic!

    2. Тип Result

    3. Методы unwrap и expect типа Result

    4. Обработка нескольких типов ошибок

    5. Оператор ?

  10. Глава 10. Cargo

    1. Создание проекта с помощью Cargo

    2. Загрузка и использование внешних зависимостей

  11. Глава 11. Ввод и вывод

    1. Ввод с клавиатуры

  12. Глава 12. Unsafe-контекст

    1. Указатели

  • Глава 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-контекст
    • Указатели
  • Книги
  • Программирование
  • Стив Клабник

  • 📚 Программирование на Rust (pdf + epub)

Эта и ещё 2 книги за 399 

По абонементу вы каждый месяц можете взять из каталога одну книгу до 700 ₽ и две книги из специальной подборки. Узнать больше

Оплачивая абонемент, я принимаю условия оплаты и её автоматического продления, указанные в оферте

Описание книги

Официальный гайд по языку программирования Rust от команды разработчиков Rust из Mozilla Foundation.

Добро пожаловать в мир Rust!

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

Авторы книги входят в команду разработчиков языка, а значит, вы получите всю информацию из первых рук – от установки языка до создания надежных и масштабируемых программ. От создания функций, выбора типов данных и привязки переменных вы перейдете к более сложным концепциям:

  • Владение и заимствование, жизненный цикл и типажи.
  • Гарантированная безопасность программ.
  • Тестирование, обработка ошибок и эффективный рефакторинг.
  • Обобщения, умные указатели, многопоточность, типажные объекты и сопоставления.
  • Работа со встроенным менеджером пакетов Cargo для создания, тестирования, документирования кода и управления зависимостями.
  • Продвинутые средства работы с Unsafe Rust.

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

После покупки предоставляется дополнительная возможность скачать книгу в формате epub.

Подробная информация

Возрастное ограничение:
16+
Дата выхода на ЛитРес:
25 февраля 2021
Дата перевода:
2021
Дата написания:
2019
Объем:
592 стр.
ISBN:
978-5-4461-1656-0
Общий размер:
8 MB
Общее кол-во страниц:
592
Размер страницы:
165 x 233 мм
Переводчик:
Андрей Логунов
Правообладатель:
Питер

Книга Стива Клабника «Программирование на Rust (pdf + epub)» — скачать в pdf или читать онлайн. Оставляйте комментарии и отзывы, голосуйте за понравившиеся.

Книга входит в серию
«Для профессионалов (Питер)»

Оставьте отзыв

На что хотите пожаловаться?

Сообщение отправлено

Мы получили Ваше сообщение.
Наши модераторы проверят книгу
в ближайшее время.
Спасибо, что помогаете нам.

Сообщение уже отправлено

Мы уже получили Ваше сообщение.
Наши модераторы проверят книгу
в ближайшее время.
Спасибо, что помогаете нам.

Поделиться отзывом на книгу

Программирование на Rust (pdf + epub)

Стив Клабник, Кэрол Николс, ещё 1 автор

Программирование на Rust (pdf + epub)PDF

Понравилась статья? Поделить с друзьями:
  • Glucosamine chondroitin msm plus hyaluronic acid инструкция по применению отзывы
  • Дермаклин дезинфицирующее средство инструкция по применению
  • Рисование по инструкции упражнение для тренинга
  • Как правильно обанкротиться физическому лицу через мфц пошаговая инструкция
  • Уфсин россии по г москве официальный сайт руководство