Using assert_eq or printing large fixed sized arrays doesn't work

感情迁移 提交于 2019-12-02 13:59:41

问题


I have written some tests where I need to assert that two arrays are equal. Some arrays are [u8; 48] while others are [u8; 188]:

#[test]
fn mul() {
    let mut t1: [u8; 48] = [0; 48];
    let t2: [u8; 48] = [0; 48];

    // some computation goes here.

    assert_eq!(t1, t2, "\nExpected\n{:?}\nfound\n{:?}", t2, t1);
}

I get multiple errors here:

error[E0369]: binary operation `==` cannot be applied to type `[u8; 48]`
 --> src/main.rs:8:5
  |
8 |     assert_eq!(t1, t2, "\nExpected\n{:?}\nfound\n{:?}", t2, t1);
  |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  |
  = note: an implementation of `std::cmp::PartialEq` might be missing for `[u8; 48]`
  = note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info)

error[E0277]: the trait bound `[u8; 48]: std::fmt::Debug` is not satisfied
 --> src/main.rs:8:57
  |
8 |     assert_eq!(t1, t2, "\nExpected\n{:?}\nfound\n{:?}", t2, t1);
  |                                                         ^^ `[u8; 48]` cannot be formatted using `:?`; if it is defined in your crate, add `#[derive(Debug)]` or manually implement it
  |
  = help: the trait `std::fmt::Debug` is not implemented for `[u8; 48]`
  = note: required by `std::fmt::Debug::fmt`

Trying to print them as slices like t2[..] or t1[..] doesn't seem to work.

How do I use assert with these arrays and print them?


回答1:


For the comparison part you can just convert the arrays to iterators and compare elementwise.

assert_eq!(t1.len(), t2.len(), "Arrays don't have the same length");
assert!(t1.iter().zip(t2.iter()).all(|(a,b)| a == b), "Arrays are not equal");



回答2:


Using slices

As a workaround, you can just use &t1[..] (instead of t1[..]) to make arrays into slices. You'll have to do this for both comparison and formatting.

assert_eq!(&t1[..], &t2[..], "\nExpected\n{:?}\nfound\n{:?}", &t2[..], &t1[..]);

or

assert_eq!(t1[..], t2[..], "\nExpected\n{:?}\nfound\n{:?}", &t2[..], &t1[..]);

Formatting arrays directly

Ideally, the original code should compile, but it doesn't for now. The reason is that the standard library implements common traits (such as Eq and Debug) for arrays of only up to 32 elements, due to lack of const generics.

Therefore, you can compare and format shorter arrays like:

let t1: [u8; 32] = [0; 32];
let t2: [u8; 32] = [1; 32];
assert_eq!(t1, t2, "\nExpected\n{:?}\nfound\n{:?}", t2, t1);



回答3:


With Iterator::eq, it is possible to compare anything that can be turned into an iterator for equality:

let mut t1: [u8; 48] = [0; 48];
let t2: [u8; 48] = [0; 48];
assert!(t1.iter().eq(t2.iter()));



回答4:


You could make Vecs out of them.

fn main() {
    let a: [u8; 3] = [0, 1, 2];
    let b: [u8; 3] = [2, 3, 4];
    let c: [u8; 3] = [0, 1, 2];

    let va: Vec<u8> = a.to_vec();
    let vb: Vec<u8> = b.to_vec();
    let vc: Vec<u8> = c.to_vec();

    println!("va==vb {}", va == vb);
    println!("va==vc {}", va == vc);
    println!("vb==vc {}", vb == vc);
}


来源:https://stackoverflow.com/questions/48013278/using-assert-eq-or-printing-large-fixed-sized-arrays-doesnt-work

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!