Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Выражения массивов и индексации массивов

Выражения массивов

Syntax
ArrayExpression[ ArrayElements? ]

ArrayElements
      Expression ( , Expression )* ,?
    | Expression ; Expression

Выражения массивов конструируют массивы. Выражения массивов бывают двух форм.

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

Синтаксис для этой формы - это разделенный запятыми список выражений единообразного типа, заключенный в квадратные скобки.

Это производит массив, содержащий каждое из этих значений в том порядке, в котором они записаны.

Синтаксис для второй формы - два выражения, разделенные точкой с запятой (;), заключенные в квадратные скобки.

Выражение перед ; называется операндом повторения.

Выражение после ; называется операндом длины.

Операнд длины должен быть либо выведенной константой, либо константным выражением типа usize (например, литералом или константным элементом).

#![allow(unused)]
fn main() {
const C: usize = 1;
let _: [u8; C] = [0; 1]; // Литерал.
let _: [u8; C] = [0; C]; // Константный элемент.
let _: [u8; C] = [0; _]; // Выведенная константа.
let _: [u8; C] = [0; (((_)))]; // Выведенная константа.
}

Note

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

Выражение массива этой формы создает массив с длиной, равной значению операнда длины, где каждый элемент является копией операнда повторения. То есть, [a; b] создает массив, содержащий b копий значения a.

Если операнд длины имеет значение больше 1, то это требует, чтобы операнд повторения имел тип, который реализует Copy, был выражением const блока или был путем к константному элементу.

Когда операнд повторения является const блоком или путем к константному элементу, он вычисляется количество раз, указанное в операнде длины.

Если это значение равно 0, то const блок или константный элемент не вычисляется вообще.

Для выражений, которые не являются ни const блоком, ни путем к константному элементу, оно вычисляется ровно один раз, а затем результат копируется количество раз, равное значению операнда длины.

#![allow(unused)]
fn main() {
[1, 2, 3, 4];
["a", "b", "c", "d"];
[0; 128];              // массив со 128 нулями
[0u8, 0u8, 0u8, 0u8,];
[[1, 0, 0], [0, 1, 0], [0, 0, 1]]; // 2D массив
const EMPTY: Vec<i32> = Vec::new();
[EMPTY; 2];
}

Выражения индексации массивов и срезов

Syntax
IndexExpressionExpression [ Expression ]

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

Для других типов выражение индексации a[b] эквивалентно *std::ops::Index::index(&a, b), или *std::ops::IndexMut::index_mut(&mut a, b) в контексте изменяемого выражения-места. Так же, как и с методами, Rust также будет вставлять операции разыменования для a повторно, чтобы найти реализацию.

Индексация начинается с нуля для массивов и срезов.

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

#![allow(unused)]
fn main() {
// линтер по умолчанию запрещает.
#![warn(unconditional_panic)]

([1, 2, 3, 4])[2];        // Вычисляется в 3

let b = [[1, 0, 0], [0, 1, 0], [0, 0, 1]];
b[1][2];                  // многомерная индексация массива

let x = (["a", "b"])[10]; // предупреждение: индекс вне границ

let n = 10;
let y = (["a", "b"])[n];  // паника

let arr = ["a", "b"];
arr[10];                  // предупреждение: индекс вне границ
}

Выражение индексации массива может быть реализовано для типов, отличных от массивов и срезов, путем реализации трейтов Index и IndexMut.