Массивы
// Copyright 2024 Google LLC
// SPDX-License-Identifier: Apache-2.0
fn main() {
let mut a: [i8; 5] = [5, 4, 3, 2, 1];
a[2] = 0;
println!("a: {a:?}");
}
-
Массивы также можно инициализировать краткой записью, например
[0; 1024]. Это удобно, когда нужно задать все элементы одинаковым значением или когда большой массив сложно инициализировать вручную. -
Значение массива
[T; N]содержитNэлементов одинакового типаT. ГдеN(длина массива) — это константа времени компиляции. Обратите внимание: длина является частью типа, поэтому[u8; 3]и[u8; 4]— это разные типы. Срезы, длина которых определяется во время выполнения, рассматриваются в курсе позднее. -
Попробуйте обратиться к элементу массива за пределами его границ. Компилятор способен определить, что индекс небезопасен, и не скомпилирует код:
// Copyright 2024 Google LLC
// SPDX-License-Identifier: Apache-2.0
fn main() {
let mut a: [i8; 5] = [5, 4, 3, 2, 1];
a[6] = 0;
println!("a: {a:?}");
}
- Обращения к массиву проверяются во время выполнения. Rust по возможности убирает эти проверки: если компилятор может доказать, что обращение безопасно, он удаляет проверку ради производительности. Их можно обойти, используя небезопасный Rust. Оптимизация настолько хороша, что трудно привести пример того, как проверки во время выполнения срабатывают. Следующий код скомпилируется, но вызовет панику во время выполнения:
// Copyright 2024 Google LLC
// SPDX-License-Identifier: Apache-2.0
fn get_index() -> usize {
6
}
fn main() {
let mut a: [i8; 5] = [5, 4, 3, 2, 1];
a[get_index()] = 0;
println!("a: {a:?}");
}
-
Мы можем использовать литералы для присваивания значений массивам.
-
Массивы не размещаются в куче. Это обычные значения фиксированного размера, известного во время компиляции, поэтому они хранятся на стеке. Это может отличаться от ожиданий студентов, пришедших из языков со сборщиком мусора, где массивы по умолчанию могут размещаться в куче.
-
У массива нельзя удалить элементы или добавить новые. Длина массива фиксирована во время компиляции, поэтому во время выполнения она не может измениться.
Отладочный вывод
-
Параметр форматирования
?предписывает макросуprintln!запросить реализацию трейта отладочного вывода:{}запрашивает форматирование по умолчанию (std::fmt::Display),{:?}– отладочное представление (std::fmt::Debug). Например, целочисленные типы и строки реализуют трейтDisplay, но для массивов реализован только трейтDebug. Поэтому использование{:?}здесь обязательно. -
Добавление
#, например{a:#?}, позволяет использовать более наглядный формат «красивой печати» с отступами и переносами строк.