Примитивный тип array
Массив фиксированного размера, обозначаемый как [T; N], где:
T— тип элементовN— неотрицательная константа времени компиляции (размер)
Синтаксис создания массивов
Существует два синтаксических способа создания массива:
- Список элементов:
[x, y, z] - Повторяющееся выражение:
[expr; N], гдеN— количество повторенийexprexprдолжно быть либо:- Значением типа, реализующего трейт
Copy - Константным значением
- Значением типа, реализующего трейт
Примечание: [expr; 0] разрешено и создаёт пустой массив. Однако expr всё равно будет вычислено, и результат будет немедленно удалён — учитывайте побочные эффекты.
Реализуемые трейты
Массивы любого размера реализуют следующие трейты (если это позволяет тип элементов):
| Трейт | Реализации |
|---|---|
Copy, Clone, Debug | Для всех массивов |
IntoIterator | Для [T; N], &[T; N] и &mut [T; N] |
PartialEq, PartialOrd, Eq, Ord | Для всех массивов |
Hash | Для всех массивов |
AsRef, AsMut | Для всех массивов |
Borrow, BorrowMut | Для всех массивов |
Особые реализации
- Default: Массивы размером от 0 до 32 (включительно) реализуют
Default, если тип элементов позволяет это. Реализации генерируются статически до размера 32. - From<Tuple>: Массивы размером от 1 до 12 (включительно) реализуют
From<Tuple>, гдеTuple— однородный кортеж соответствующей длины.
Приведение типов
Массивы приводятся к срезам ([T]), поэтому методы срезов можно вызывать на массивах. Большая часть API для работы с массивами предоставляется именно через срезы.
Важно: Срезы имеют динамический размер и не приводятся к массивам. Вместо этого используйте:
slice.try_into().unwrap()<ArrayType>::try_from(slice).unwrap()
Методы реализации
impl<T, const N: usize> [T; N]
| Метод | Версия | Описание |
|---|---|---|
map<F, U>(self, f: F) -> [U; N] | 1.55.0 | Применяет функцию к каждому элементу, возвращая массив того же размера |
try_map<F, R>(self, f: F) -> ... | nightly | Вариация map с обработкой ошибок |
as_slice(&self) -> &[T] | 1.57.0 (const) | Возвращает срез всего массива |
as_mut_slice(&mut self) -> &mut [T] | 1.57.0 (const) | Возвращает изменяемый срез всего массива |
each_ref(&self) -> [&T; N] | 1.77.0 (const) | Возвращает массив ссылок на элементы |
each_mut(&mut self) -> [&mut T; N] | 1.77.0 (const) | Возвращает массив изменяемых ссылок на элементы |
split_array_ref<const M>(&self) -> (&[T; M], &[T]) | nightly | Разделяет массив на две части по индексу M |
split_array_mut<const M>(&mut self) -> (&mut [T; M], &mut [T]) | nightly | Разделяет изменяемый массив на две части |
rsplit_array_ref<const M>(&self) -> (&[T], &[T; M]) | nightly | Разделяет массив с конца |
rsplit_array_mut<const M>(&mut self) -> (&mut [T], &mut [T; M]) | nightly | Разделяет изменяемый массив с конца |
impl<const N: usize> [u8; N]
| Метод | Версия | Описание |
|---|---|---|
as_ascii(&self) -> Option<&[AsciiChar; N]> | nightly | Преобразует байты в ASCII символы |
as_ascii_unchecked(&self) -> &[AsciiChar; N] | nightly | Небезопасное преобразование в ASCII |
impl<T, const N: usize> [MaybeUninit<T>; N]
| Метод | Версия | Описание |
|---|---|---|
transpose(self) -> MaybeUninit<[T; N]> | nightly | Транспонирование массива MaybeUninit |
impl<T, const N: usize> [Option<T>; N]
| Метод | Версия | Описание |
|---|---|---|
transpose(self) -> Option<[T; N]> | nightly | Транспонирование массива Option |
Реализации трейтов
From преобразования
| Источник | Назначение | Версия | Описание |
|---|---|---|---|
&[T; N] | Cow<'a, [T]> | 1.77.0 | Создание Cow без аллокации |
&[T; N] | Vec<T> | 1.74.0 | Копирование в Vec |
[(K, V); N] | BTreeMap<K, V> | 1.56.0 | Создание BTreeMap из массива пар |
[(K, V); N] | HashMap<K, V> | 1.56.0 | Создание HashMap из массива пар |
[T; N] | Arc<[T]> | 1.74.0 | Перемещение в Arc |
[T; N] | Box<[T]> | 1.45.0 | Перемещение в кучу |
[T; N] | Vec<T> | 1.44.0 | Перемещение в Vec |
[u16; 8] | IpAddr | 1.17.0 | IPv6 адрес из массива |
[u8; 16] | IpAddr | 1.17.0 | IPv6 адрес из байтов |
[u8; 4] | IpAddr | 1.17.0 | IPv4 адрес из байтов |
TryFrom преобразования
| Источник | Назначение | Версия | Описание |
|---|---|---|---|
&[T] | &[T; N] | 1.34.0 | Попытка создания ссылки на массив из среза |
&[T] | [T; N] | 1.34.0 | Копирование из среза в массив |
&mut [T] | &mut [T; N] | 1.34.0 | Создание изменяемой ссылки |
Box<[T]> | Box<[T; N]> | 1.43.0 | Попытка преобразования Box без аллокации |
Vec<T> | [T; N] | 1.48.0 | Получение массива из Vec |
Примеры
Базовое использование
#![allow(unused)] fn main() { let mut array: [i32; 3] = [0; 3]; array[1] = 1; array[2] = 2; assert_eq!([1, 2], &array[1..]); // Итерация по значению for x in array { print!("{x} "); } // Итерация по ссылке for x in &array { } }
Преобразования
#![allow(unused)] fn main() { let bytes: [u8; 3] = [1, 0, 2]; assert_eq!(1, u16::from_le_bytes(<[u8; 2]>::try_from(&bytes[0..2]).unwrap())); assert_eq!(512, u16::from_le_bytes(bytes[1..3].try_into().unwrap())); }
Использование map
#![allow(unused)] fn main() { let x = [1, 2, 3]; let y = x.map(|v| v + 1); assert_eq!(y, [2, 3, 4]); }
Изменения в изданиях Rust
Rust 2015/2018
array.into_iter() создаёт итератор по ссылкам (автоматическое приведение к срезу).
Rust 2021+
array.into_iter() работает через IntoIterator по значению. Для итерации по ссылкам используйте array.iter().
Рекомендация: Для совместимости между изданиями:
- Используйте
iter()для итерации по ссылкам - Используйте
IntoIterator::into_iter(array)для итерации по значению - Избегайте
array.into_iter()в изданиях 2015/2018
Примечания по производительности
Метод map на больших массивах может не оптимизироваться оптимально и потреблять много стекового пространства в режиме отладки. В критическом по производительности коду:
- Избегайте цепочек
mapна больших массивах - Рассмотрите использование
Iterator::mapчерез.iter()или.into_iter()