Срез - это набор элементов динамического массива, списка List<T> или строки, расположенных последовательно либо с некоторым шагом.
Срез имеет вид:
a[from:to]
или
a[from:to:step]
или
a?[from:to]
или
a?[from:to:step]
и содержит копию элементов исходного контейнера в диапазоне [from
,
to) с
шагом step. Запись [from,
to) означает, что элемент с индексом
from включается в
диапазон, а элемент с индексом to - не включается.
Значения from
,
to, step
должны быть целыми.
Если step не указывается, то предполагается, что step=1, т.е. элементы расположены непрерывно.
Тип среза совпадает с типом контейнера: срез элементов массива представляет собой массив, срез строки - строку и срез для List<T> также принадлежит к типу List<T>.
Для обычных срезов исключение генерируется в следующих случаях. Если индекс from выходит за границы, то во время выполнения программы возникает исключение. Индекс to может выходить за границы на 1, т.е. находиться в диапазоне [-1..a.Count] для динамических массивов и списков List<T> и в диапазоне [0..s.Length+1] для строк, в противном случае также возникает исключение.
Если step=0, то для всех видов срезов генерируется исключение.
Срезы вида
a?
называются безопасными срезами и во всех остальных случаях не генерируют
исключений. Они работают следующим образом. Вначале контейнер считается
бесконечным в обе стороны и срез выбирает в нём определённые элементы. После
этого в срезе оставляются только те элементы, которые принадлежат исходному
контейнеру.
Приведём ряд примеров:
var a := Arr(0,1,2,3,4,5,6);
Println(a[2:5]); // [2,3,4]
Println(a[2:a.Length]); // [2,3,4,5,6]
Println(a[2:1000]); // Исключение!
Println(a?[2:1000]); // [2,3,4,5,6]
Println(a[2:7:2]); // [2,4,6]
Println(a[2:0]); // пустой массив
var s := '0123456';
Println(s[2:5]); // 123
Println(s[0:2]); // Исключение!
Println(s?[0:2]); // 12
Println(s?[-2::2]); // 135
Println(s[2:s.Length]); // 12345
Шаг step может быть отрицательным. Например:
var a := Arr(0,1,2,3,4,5,6);
Println(a[5:2:-1]); // [5,4,3]
Println(a[2:5:-1]); // пустой массив
Println(a[a.Length-1:-1:-2]); // [6,4,2,0]
В записи среза выражение from или выражение to могут быть пропущены, в этом случае в срез попадают все элементы с соответствующей стороны. Если step>0, то пропущенный from полагается равным индексу первого элемента, пропущенный to полагается равным индексу последнего элемента + 1. Если step<0, то пропущенный from полагается равным индексу последнего элемента, а пропущенный to - индексу первого элемента - 1.
Например:
var s := '0123456';
Println(s[2:]); // 23456
Println(s[:4]); // 012
Println(s[::-1]); // 6543210
Родственным к срезам является метод Slice, определенный для динамических массивов, списков List<T>, строк и последовательностей. Однако, смысл параметров у него - другой: a.Slice(from,step,count).