Подтвердить что ты не робот

Почему 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 элементов, но затем прекращает обнаружение. Или почему это не работает?

4b9b3361

Ответ 1

К сожалению, Rust пока не поддерживает целые числа как общие параметры. Поэтому нелегко реализовать черту (например, Debug) для каждого массива [T; N] [T; N]. В настоящее время стандартная библиотека использует макрос, чтобы легко реализовать черту на всю длину до 32.

Чтобы вывести массив, вы можете легко преобразовать его в срез (&[T]) следующим образом:

let a = [0; 33];
println!("{:?}", &a[..]);

Кстати: обычно вы можете получить срез из массива, просто добавив префикс &, но аргументы println работают немного по-другому, поэтому вам нужно добавить индекс полного диапазона [..].


Ситуация, вероятно, улучшится в будущем. RFC 2000: Const Generics уже принят и в основном реализован в компиляторе. Это позволило бы использовать блоки impl по всей длине массива. Вы можете отслеживать статус внедрения и стабилизации по соответствующей проблеме отслеживания.