为什么 println!仅适用于长度小于 33 的数组?

Why does println! work only for arrays with a length less than 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 个元素长度的类型,但随后放弃了它的检测。或者为什么它不起作用?

从 Rust 1.47 (2020-10-08) 开始,this is no longer true! 现在几乎所有 traits 都为任意长度的数组实现了。所以你现在可以打印长度为 33!

的数组

下面的旧答案供参考。


遗憾的是,Rust 尚不支持整数作为泛型参数。因此,为每个数组 [T; N] 实现一个特征(如 Debug)并不容易。目前,标准库使用宏轻松实现所有长度不超过 32 的特征。

要输出数组,您可以通过这种方式轻松地将其转换为切片 (&[T]):

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

顺便说一句:通常你可以通过简单地前缀 & 从数组中获取切片,但是 println 参数的工作方式有点不同,所以你需要添加全范围索引 [..].


这种情况将来可能会有所改善。 RFC 2000: Const Generics has already been accepted and mostly implemented in the compiler. It would allow for impl blocks generic over the length of the array. You can track the status of implementation and stabilization on the corresponding tracking issue.