Skip to content

Commit

Permalink
Merge pull request #1286 from rust-lang-ru/gitlocalize-26732
Browse files Browse the repository at this point in the history
Translate ch06-02-match.md via GitLocalize
  • Loading branch information
ava57r authored Oct 16, 2023
2 parents c3ce8c5 + 3b181bc commit 4981ad4
Showing 1 changed file with 12 additions and 10 deletions.
22 changes: 12 additions & 10 deletions rustbook-ru/src/ch06-02-match.md
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
<!-- Old heading. Do not remove or links may break. -->

<a id="the-match-control-flow-operator"></a>

## Управляющая конструкция `match`

В Rust есть чрезвычайно мощный механизм управления потоком, именуемый `match`, который позволяет сравнивать значение с различными шаблонами и затем выполнять код в зависимости от того, какой из шаблонов совпал. Шаблоны могут состоять из литеральных значений, имён переменных, подстановочных знаков и многого другого; в главе 18 рассматриваются все различные виды шаблонов и то, что они делают. Сила `match` заключается в выразительности шаблонов и в том, что компилятор проверяет, что все возможные случаи обработаны.
В Rust есть чрезвычайно мощный механизм управления потоком, именуемый `match`, который позволяет сравнивать значение с различными шаблонами и затем выполнять код в зависимости от того, какой из шаблонов совпал. Шаблоны могут состоять из литеральных значений, имён переменных, подстановочных знаков и многого другого; в главе 18 рассматриваются все различные виды шаблонов и то, что они делают. Сила <code>match</code> заключается в выразительности шаблонов и в том, что компилятор проверяет, что все возможные случаи обработаны.

Думайте о выражении `match` как о машине для сортировки монет: монеты скользят по дорожке с различными по размеру отверстиями, и каждая монета падает через первое попавшееся отверстие, в которое она поместилась. Таким же образом значения проходят через каждый шаблон в `match`, и при первом же "подходящем" шаблоне значение попадает в соответствующий блок кода, который будет использоваться во время выполнения.

Expand All @@ -14,21 +16,21 @@

<span class="caption">Листинг 6-3: Перечисление и выражение <code>match</code>, использующее в качестве шаблонов его варианты</span>

Давайте разберём `match` в функции `value_in_cents`. Сначала мы используем ключевое слово `match`, за которым следует выражение, которое в данном случае является значением `coin`. Это кажется очень похожим на выражение, используемое в `if`, но есть большая разница: в `if` выражение должно возвращать булево значение, а здесь оно может возвращать любой тип. Типом `coin` в данном примере является перечисление `Coin`, которое мы определили в первой строке.
Давайте разберём `match` в функции `value_in_cents`. Сначала пишется ключевое слово `match`, затем следует выражение, которое в данном случае является значением `coin`. Это выглядит очень похоже на условное выражение, используемое в `if`, но есть большая разница: с `if` выражение должно возвращать <em>булево значение</em>, а здесь это может быть любой тип. Тип `coin` в этом примере перечисление типа <code>Coin</code>, объявленное в строке 1.

Далее идут ветки `match`. Ветки состоят из двух частей: шаблон и некоторый код. Здесь первая ветка имеет шаблон, который является значением `Coin::Penny`, затем идёт оператор `=>`, который разделяет шаблон и код для выполнения. Код в этом случае - это просто значение `1`. Каждая ветка отделяется от последующей при помощи запятой.

Когда выполняется выражение `match`, оно сравнивает полученное значение с образцом каждой ветки по порядку. Если шаблон совпадает со значением, то выполняется код, связанный с этим шаблоном. Если этот шаблон не соответствует значению, то выполнение продолжается со следующей ветки, так же, как в автомате по сортировке монет. У нас может быть столько веток, сколько нужно: в листинге 6-3 наш `match` состоит из четырёх веток.
Когда выполняется выражение `match`, оно сравнивает полученное значение с образцом каждого ответвления по порядку. Если образец совпадает со значением, то выполняется код, связанный с этим образцом. Если этот образец не соответствует значению, то выполнение продолжается со следующей ветки, так же, как в автомате по сортировке монет. У нас может быть столько ответвлений, сколько нужно: в листинге 6-3 наш `match` состоит из четырёх ответвлений.

Код, связанный с каждой веткой, является выражением, а полученное значение выражения в соответствующей ветке — это значение, которое возвращается для всего выражения `match`.
Код, связанный с каждым ответвлением, является выражением, а полученное значение выражения в соответствующем ответвлении — это значение, которое возвращается для всего выражения `match`.

Обычно фигурные скобки не используются, если код совпадающей ветви невелик, как в листинге 6-3, где каждая ветвь просто возвращает значение. Если вы хотите выполнить несколько строк кода в одной ветви, вы должны использовать фигурные скобки, а запятая после этой ветви необязательна. Например, следующий код печатает "Lucky penny!" каждый раз, когда метод вызывается с `Coin::Penny`, но при этом он возвращает последнее значение блока - `1`:

```rust
{{#rustdoc_include ../listings/ch06-enums-and-pattern-matching/no-listing-08-match-arm-multiple-lines/src/main.rs:here}}
```

### Шаблоны, которые привязывают значения<a id="patterns-that-bind-to-values"></a>
### Образцы, привязывающие значения

Есть ещё одно полезное качество у веток в выражении <code>match</code>: они могут привязываться к частям тех значений, которые совпали с шаблоном. Благодаря этому можно извлекать значения из вариантов перечисления.

Expand Down Expand Up @@ -64,21 +66,21 @@

<span class="caption">Листинг 6-5: Функция, использующая выражение <code>match</code> для <code>Option&lt;i32&gt;</code></span>

Давайте более подробно рассмотрим первое выполнение `plus_one`. Когда мы вызываем `plus_one(five)`, переменная `x` в теле `plus_one` будет иметь значение `Some(5)`. Затем мы сравниваем это значение с каждой ветвью выражения match.
Давайте более подробно рассмотрим первое выполнение `plus_one`. Когда мы вызываем `plus_one(five)`, переменная `x` в теле `plus_one` будет иметь значение `Some(5)`. Затем мы сравниваем это значение с каждой ветвью сопоставления:

```rust,ignore
{{#rustdoc_include ../listings/ch06-enums-and-pattern-matching/listing-06-05/src/main.rs:first_arm}}
```

Значение `Some(5)` не соответствует шаблону `None`, поэтому мы продолжаем со следующей ветки.
Значение `Some(5)` не соответствует образцу `None`, поэтому мы продолжаем со следующим ответвлением:

```rust,ignore
{{#rustdoc_include ../listings/ch06-enums-and-pattern-matching/listing-06-05/src/main.rs:second_arm}}
```

Совпадает ли `Some(5)` с шаблоном `Some(i)`? Да, это так! У нас такой же вариант. Тогда переменная `i` привязывается к значению, содержащемуся внутри `Some`, поэтому `i` получает значение `5`. Затем выполняется код ассоциированный для данной ветки, поэтому мы добавляем 1 к значению `i` и создаём новое значение `Some` со значением `6` внутри.
Совпадает ли `Some(5)` с образцом `Some(i)`? Да, это так! У нас такой же вариант. Тогда переменная `i` привязывается к значению, содержащемуся внутри `Some`, поэтому `i` получает значение `5`. Затем выполняется код ассоциированный для данного ответвления, поэтому мы добавляем 1 к значению `i` и создаём новое значение `Some` со значением `6` внутри.

Теперь давайте рассмотрим второй вызов `plus_one` в листинге 6-5, где `x` является `None`. Мы входим в выражение `match` и сравниваем значение с первой веткой.
Теперь давайте рассмотрим второй вызов `plus_one` в листинге 6-5, где `x` является `None`. Мы входим в выражение `match` и сравниваем значение с первым ответвлением:

```rust,ignore
{{#rustdoc_include ../listings/ch06-enums-and-pattern-matching/listing-06-05/src/main.rs:first_arm}}
Expand Down Expand Up @@ -112,7 +114,7 @@ Rust знает, что мы не описали все возможные сл
{{#rustdoc_include ../listings/ch06-enums-and-pattern-matching/no-listing-15-binding-catchall/src/main.rs:here}}
```

Для первых двух веток шаблонами являются литеральные значения 3 и 7. Для последней ветки, которая охватывает все остальные возможные значения, шаблоном является переменная, которую мы решили назвать `other`. Код, выполняемый для другой ветки, использует эту переменную, передавая её в функцию move_player.
Для первых двух веток шаблонами являются литеральные значения 3 и 7. Для последней ветки, которая охватывает все остальные возможные значения, шаблоном является переменная, которую мы решили назвать `other`. Код, выполняемый для ветки `other`, использует эту переменную, передавая её в функцию `move_player`.

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

Expand Down

0 comments on commit 4981ad4

Please sign in to comment.