Почему println! работать только для массивов длиной менее 33?
В Rust это работает:
fn main() {
let a = [0; 32];
println!("{:?}", a);
}
Но это не так:
fn main() {
let a = [0; 33];
println!("{:?}", a);
}
Ошибка компиляции:
error[E0277]: the trait bound `[{integer}; 33]: std::fmt::Debug` is not satisfied
--> src/main.rs:3:22
|
3 | println!("{:?}", a);
| ^ the trait `std::fmt::Debug` is not implemented for `[{integer}; 33]`
|
= note: `[{integer}; 33]` cannot be formatted using `:?`; if it is defined in your crate, add `#[derive(Debug)]` or manually implement it
= note: required by `std::fmt::Debug::fmt`
Я предполагаю, что функция std::fmt::Debug
каким-то образом обнаруживает типы длиной до 32 элементов, но затем отбрасывает это обнаружение. Или почему это не работает?
1 ответ:
К сожалению, Rust пока не поддерживает целые числа в качестве общих параметров. Поэтому нелегко реализовать признак (например,
Debug
) для каждого массива[T; N]
. В настоящее время стандартная библиотека использует макрос, чтобы легко реализовать признак для всей длины до 32.Чтобы вывести массив, вы можете легко преобразовать его в срез (
&[T]
) следующим образом:let a = [0; 33]; println!("{:?}", &a[..]);
Кстати: обычно вы можете получить срез из массива, просто добавив префикс
&
, но аргументыprintln
работают немного иначе, поэтому вам нужно добавить индекс полного диапазона[..]
.
Ситуация, вероятно, улучшится в будущем. RFC 2000: const Generics уже принят и допускает блокиimpl
generic по длине массива. Вы можете отслеживать состояние реализации и стабилизации посоответствующему вопросу отслеживания .