Browse Source

Merge pull request #1115 from rust-lang-ru/gitlocalize-21681

Translate ch04-03-slices.md via GitLocalize
pull/1116/head
Alexander A 3 years ago committed by GitHub
parent
commit
f88500e4a2
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 22
      rustbook-ru/src/ch04-03-slices.md

22
rustbook-ru/src/ch04-03-slices.md

@ -78,7 +78,7 @@ fn second_word(s: &String) -> (usize, usize) {
<img alt="world containing a pointer to the 6th byte of String s and a length 5" src="img/trpl04-06.svg" class=""> <img alt="world containing a pointer to the 6th byte of String s and a length 5" src="img/trpl04-06.svg" class="">
<span class="caption">Рисунок 4-6: Фрагмент строки, относящийся к части <code>String</code></span> <span class="caption">Рисунок 4-6: Строковый срез ссылается на часть <code>String</code></span>
С синтаксисом Rust `..`, если вы хотите начать с индекса 0, вы можете отбросить значение перед двумя точками. Другими словами, они равны: С синтаксисом Rust `..`, если вы хотите начать с индекса 0, вы можете отбросить значение перед двумя точками. Другими словами, они равны:
@ -111,9 +111,7 @@ let slice = &s[0..len];
let slice = &s[..]; let slice = &s[..];
``` ```
> Внимание: Индексы среза строк должны соответствовать границам UTF-8 символов. Если вы попытаетесь получить срез нарушая границы символа в котором больше одного байта, то вы получите ошибку времени исполнения. В рамках этой главы мы будем предполагать только ASCII кодировку. Более детальное обсуждение UTF-8 находится в секции ["Сохранение текста с кодировкой UTF-8 в строках"] > Примечание. Индексы диапазона срезов строк должны располагаться на допустимых границах символов UTF-8. Если вы попытаетесь создать фрагмент строки нарушая границы символа в котором больше одного байта, ваша программа завершится с ошибкой. В целях введения срезов строк мы предполагаем, что ASCII в этом разделе используется только; более подробное обсуждение обработки UTF-8 находится в разделе [«Сохранение закодированного текста UTF-8 со строками»].<!-- ignore --> раздел главы 8.
> <!-- ignore -->
> Главы 8.
Давайте используем полученную информацию и перепишем метод `first_word` так, чтобы он возвращал срез. Для обозначения типа "срез строки" существует запись `&str`: Давайте используем полученную информацию и перепишем метод `first_word` так, чтобы он возвращал срез. Для обозначения типа "срез строки" существует запись `&str`:
@ -125,7 +123,7 @@ let slice = &s[..];
Мы получаем индекс конца слова так же, как в листинге 4.7, ища первое вхождение пробела. Когда мы находим пробел, мы возвращаем фрагмент строки, используя начало строки и индекс пробела в качестве начального и конечного индексов. Мы получаем индекс конца слова так же, как в листинге 4.7, ища первое вхождение пробела. Когда мы находим пробел, мы возвращаем фрагмент строки, используя начало строки и индекс пробела в качестве начального и конечного индексов.
Теперь, вызвав метод first_word, мы получим одно единственное значение, которое привязано к нижележащим данным. Значение, которое составлено из ссылки на начальную точку среза и количества элементов в срезе. Теперь, когда мы вызываем `first_word`, мы возвращаем одно значение, привязанное к базовым данным. Значение состоит из ссылки на начальную точку среза и количества элементов в срезе.
Аналогичным образом можно переписать и второй метод `second_word`: Аналогичным образом можно переписать и второй метод `second_word`:
@ -133,7 +131,7 @@ let slice = &s[..];
fn second_word(s: &String) -> &str { fn second_word(s: &String) -> &str {
``` ```
Теперь есть простое API, работу которого гораздо сложнее испортить, потому что компилятор обеспечивает нам то, что ссылки на `String` останутся действительными. Помните ошибку в программе листинга 4-8, когда мы получили индекс конца первого слова, но затем очистили строку, так что она стала недействительной? Тот код был логически некорректным, хотя не показывал никаких ошибок. Проблемы возникли бы позже, если бы мы попытались использовать индекс первого слова для пустой строки. Срезы делают невозможной данную ошибку и позволяют понять о наличии проблемы гораздо раньше. Так, использование версии метода `first_word` со срезом вернёт ошибку компиляции: Теперь у нас есть простой API, который гораздо сложнее испортить, потому что компилятор гарантирует, что ссылки в `String` останутся действительными. Помните ошибку в программе в листинге 4-8, когда мы получили индекс до конца первого слова, но затем очистили строку, так что наш индекс стал недействительным? Этот код был логически неправильным, но не показывал немедленных ошибок. Проблемы проявятся позже, если мы попытаемся использовать индекс первого слова с пустой строкой. Срезы делают эту ошибку невозможной и сообщают нам о проблеме с нашим кодом гораздо раньше. Так, использование версии метода `first_word` со срезом вернёт ошибку компиляции:
<span class="filename">Файл: src/main.rs</span> <span class="filename">Файл: src/main.rs</span>
@ -161,17 +159,17 @@ fn second_word(s: &String) -> &str {
let s = "Hello, world!"; let s = "Hello, world!";
``` ```
Тип `s` здесь является `&str` срезом, указывающим на конкретное место в бинарном файле программы. Это также объясняет, почему строковый литерал является неизменяемым, потому что тип `&str` это неизменяемая ссылка. Тип `s` здесь `&str`: это срез, указывающий на эту конкретную точку двоичного файла. Вот почему строковые литералы неизменяемы; `&str` неизменяемая ссылка.
#### Строковые срезы как параметры #### Строковые срезы как параметры
Знание о том, что можно брать срезы строковых литералов и `String` строк приводит к ещё одному улучшению метода `first_word` улучшению его сигнатуры: Знание того, что вы можете брать срезы литералов и `String` значений, приводит нас к ещё одному улучшению `first_word`, и это его сигнатура:
```rust,ignore ```rust,ignore
fn first_word(s: &String) -> &str { fn first_word(s: &String) -> &str {
``` ```
Более опытные разработчики Rust написали бы сигнатуру из листинга 4-9, потому что она позволяет использовать одну функцию для значений обоих типов `&String` и `&str`. Более опытный пользователь Rustacean вместо этого написал бы сигнатуру, показанную в листинге 4.9, потому что это позволяет нам использовать одну и ту же функцию как для значений `&String`, так и для значений `&str`.
```rust,ignore ```rust,ignore
{{#rustdoc_include ../listings/ch04-understanding-ownership/listing-04-09/src/main.rs:here}} {{#rustdoc_include ../listings/ch04-understanding-ownership/listing-04-09/src/main.rs:here}}
@ -207,16 +205,16 @@ let slice = &a[1..3];
assert_eq!(slice, &[2, 3]); assert_eq!(slice, &[2, 3]);
``` ```
Данный срез имеет тип `&[i32]`. Он работает таким же образом, как и строковый срез, сохраняя ссылку на первый элемент и длину. Вы будете использовать данную разновидность среза для всех видов коллекций. Мы обсудим коллекции детально, когда будем говорить про векторы в Главе 8. Этот срез имеет тип `&[i32]`. Он работает так же, как и срезы строк, сохраняя ссылку на первый элемент и его длину. Вы будете использовать этот вид фрагмента для всех видов других коллекций. Мы подробно обсудим эти коллекции, когда будем говорить о векторах в главе 8.
## Итоги ## Итоги
Концепции владения, заимствования и срезов обеспечивают защиту использования памяти в Rust. Rust даёт вам возможность контролировать использование памяти тем же способом, как другие языки системного программирования, но дополнительно предоставляет возможность автоматической очистки данных, когда их владелец покидает область видимости функции. Это означает, что не нужно писать и отлаживать дополнительный код, чтобы добиться такого контроль. Концепции владения, заимствования и срезов обеспечивают безопасность памяти в программах на Rust во время компиляции. Язык Rust даёт вам контроль над использованием памяти так же, как и другие языки системного программирования, но то, что владелец данных автоматически очищает эти данные, когда владелец выходит за рамки, означает, что вам не нужно писать и отлаживать дополнительный код, чтобы получить этот контроль.
Владение влияет на множество других частей и концепций языка Rust. Мы будем говорить об этих концепциях на протяжении оставшихся частей книги. Давайте перейдём к Главе 5 и рассмотрим группировку частей данных в структуры `struct`. Владение влияет на множество других частей и концепций языка Rust. Мы будем говорить об этих концепциях на протяжении оставшихся частей книги. Давайте перейдём к Главе 5 и рассмотрим группировку частей данных в структуры `struct`.
[Главе 13]: ch13-02-iterators.html [Главе 13]: ch13-02-iterators.html
[Главе 6.]: ch06-02-match.html#patterns-that-bind-to-values [Главе 6.]: ch06-02-match.html#patterns-that-bind-to-values
["Сохранение текста с кодировкой UTF-8 в строках"]: ch08-02-strings.html#storing-utf-8-encoded-text-with-strings [«Сохранение закодированного текста UTF-8 со строками»]: ch08-02-strings.html#storing-utf-8-encoded-text-with-strings
[разделе «Неявное приведение Deref с функциями и методами».]: ch15-02-deref.html#implicit-deref-coercions-with-functions-and-methods [разделе «Неявное приведение Deref с функциями и методами».]: ch15-02-deref.html#implicit-deref-coercions-with-functions-and-methods
Loading…
Cancel
Save