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

29
在 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个回答

34

从Rust 1.47(2020-10-08)开始,这不再是真的 现在几乎所有的特征都实现了任意长度数组。因此,您现在可以打印长度为33的数组

下面是参考旧答案。


很遗憾,Rust目前还不支持整数作为泛型参数。因此,很难为每个数组 [T; N] 实现一个trait(如Debug)。目前,标准库使用宏来轻松地为所有长度最多为32的数组实现该trait。
要输出数组,你可以轻松地将其转换为切片(&[T]),方法如下:
let a = [0; 33];
println!("{:?}", &a[..]);

顺便说一下:通常情况下,您可以通过简单地添加前缀&来从数组中获取一个切片,但是println参数的工作方式有些不同,因此您需要添加完整的范围索引[..]
未来情况可能会有所改善。RFC 2000:Const Generics已经被接受并在编译器中得到了大部分实现。它将允许impl块针对数组长度进行泛型。您可以在相应的跟踪问题上跟踪实现和稳定状态。

4
这是一个链接,指向 Rust 语言核心库中的一个宏实现,可能会有所帮助。链接如下:https://github.com/rust-lang/rust/blob/b30d8969e86fa2c9dd3b8e2e28ddda2202331f0f/src/libcore/array.rs#L112。 - awesoon

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接