2015-10-09 11 views
18

A Rust, questo funziona:Perché println! funziona solo per gli array con una lunghezza inferiore a 33?

fn main() { 
    let a = [0; 32]; 
    println!("{:?}", a); 
} 

ma questo non lo fa: l'errore

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

Compile:

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` 

Presumo che la funzione std::fmt::Debug rileva in qualche modo i tipi fino ad un lunghezza di 32 elementi, ma poi rilascia il rilevamento. O perché non funziona?

risposta

19

Purtroppo, Rust non supporta ancora gli interi come parametri generici. Pertanto non è facile implementare un tratto (come Debug) per ogni array [T; N]. Attualmente, la libreria standard utilizza una macro di implementare facilmente il tratto per tutti di lunghezza fino a 32.

Per produrre la matrice, si può facilmente convertirlo in una fetta (&[T]) in questo modo:

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

A proposito: in genere è possibile ottenere una porzione da una matrice semplicemente prefiggendo &, ma gli argomenti println funzionano in modo leggermente diverso, quindi è necessario aggiungere l'indice dell'intervallo completo [..].

+4

[Solo un collegamento all'implementazione della macro] (https://github.com/rust-lang/rust/blob/b30d8969e86fa2c9dd3b8e2e28ddda2202331f0f/src/libcore/array.rs#L112) - Immagino, potrebbe essere utile. – soon

Problemi correlati