Тип среза в Rust

Срез — это частичная ссылка на значение данных.

Название «slice» часто встречается на уроках биологии. При изготовлении препаратов для микроскопа нам нужно брать срезы с организма для наблюдения под микроскопом. В Rust срез означает примерно то же самое, за исключением того, что он берёт ссылку из данных.

Срез строки

Простейший и наиболее часто используемый тип среза данных — это срез строки (String Slice).

Пример

fn main() {
    let s = String::from("broadcast");

    let part1 = &s[0..5];
    let part2 = &s[5..9];

    println!("{}={}+{}", s, part1, part2);
}

Вывод:

broadcast=broad+cast

Приведённая выше диаграмма объясняет принцип среза строки (Примечание: строковый тип в Rust по сути записывает начальную позицию и длину символов в памяти; пока нам достаточно понимать это).

Использование..Синтаксис для выражения диапазонов уже встречался в главе о циклах.x..yпредставляет[x, y)математический смысл...Операнд можно опустить с обеих сторон:

..y 等价于 0..y
x.. 等价于位置 x 到数据结束
.. 等价于位置 0 到结束

Примечание:Пока старайтесь не использовать неанглийские символы в строках из-за проблем с кодировкой. Конкретные причины будут объяснены в главе "String".

Строке, на которую ссылается срез, запрещено изменять своё значение:

Пример

fn main() {
    let mut s = String::from("example");
    let slice = &s[0..3];
    s.push_str("yes!"); // Ошибка
    println!("slice = {}", slice);
}

Эта программа некорректна.

s частично заимствована, поэтому изменять её значение запрещено.

На самом деле, к этому моменту вы, должно быть, задаётесь вопросом: почему каждый раз, когда мы используем строку, нам приходится писать это такString::from("example"), а просто написать"example"разве это не сработает?

На этом этапе мы должны различать концептуальную разницу между этими двумя. В Rust есть два часто используемых строковых типа: str и String. str — это базовый тип языка Rust, который представляет собой строковый срез (String Slice), обсуждаемый в этой главе, и часто появляется в виде ссылки (&str).

Любая строковая константа, заключённая в двойные кавычки, имеет общий тип&str:

let s = "hello";

Здесь s — переменная типа &str.

Тип String — это тип данных, предоставляемый стандартной публичной библиотекой Rust, и его функциональность более полна — он поддерживает практичные операции, такие как добавление строк и очистку. Помимо атрибута начальной позиции символа и атрибута длины строки, общих для String и str, String также имеет атрибут ёмкости.

И String, и str поддерживают срезы, а результатом среза являются данные типа &str.

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

let slice = &s[0..3];

Есть быстрый способ преобразовать String в &str:

let s1 = String::from("hello");
let s2 = &s1[..];

Срез не-String

Помимо строк, некоторые другие линейные структуры данных также поддерживают операции срезов, например массивы:

Пример

fn main() {
    let arr = [1, 3, 5, 7, 9];
    let part = &arr[0..3];
    for i in part.iter() {
        println!("{}", i);
    }
}

Вывод:

1
3
5
Другие расширения