【问题标题】:Using assert_eq or printing large fixed sized arrays doesn't work使用 assert_eq 或打印大型固定大小的数组不起作用
【发布时间】:2018-06-09 08:15:26
【问题描述】:

我已经编写了一些测试,我需要断言两个数组相等。有些数组是[u8; 48],有些是[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);
}

我在这里遇到多个错误:

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`

尝试将它们打印为像 t2[..]t1[..] 这样的切片似乎不起作用。

如何将assert 与这些数组一起使用并打印它们?

【问题讨论】:

  • 您必须为每个元素单独声明。

标签: arrays rust slice assert


【解决方案1】:

使用Iterator::eq,可以比较任何可以转换为相等迭代器的东西:

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

【讨论】:

    【解决方案2】:

    你可以把它们变成Vecs。

    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);
    }
    

    【讨论】:

    • vec!(a) 将创建一个单元素向量,该元素是一个切片。然后这些内部切片进行比较,因为它们的长度小于 32。
    • 谢谢。将其更改为to_vec()
    • 虽然在技术上是正确的,但我不会按原样推荐这个答案,因为它不必要地分配内存来创建 Vec
    【解决方案3】:

    使用切片

    作为一种解决方法,您可以只使用 &amp;t1[..](而不是 t1[..])将数组制作成切片。您必须为比较和格式化这样做。

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

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

    直接格式化数组

    理想情况下,原始代码应该可以编译,但现在还不行。原因是标准库implements common traits(如EqDebug)对于最多只有32个元素的数组,由于lack of const generics

    因此,您可以比较和格式化较短的数组,例如:

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

    【讨论】:

      【解决方案4】:

      对于比较部分,您可以将数组转换为迭代器并按元素进行比较。

      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");
      

      【讨论】:

      • 这在数组大小不同并且仅在最短数组的最后一个元素之后才不同时不起作用。如果 PO 绝对确定他们只会有两个 [T; N] 和相同的 N,那很好,但如果它发生变化,那将是一个棘手的错误。
      • @mcarton 没错,我为此添加了另一个断言。
      • 还有itertools::Itertools::all_equal 就是这样做的。
      • 还有Iterator::eq
      猜你喜欢
      • 2012-03-17
      • 2011-07-11
      • 1970-01-01
      • 1970-01-01
      • 2017-02-11
      • 2013-01-24
      • 1970-01-01
      • 2014-05-25
      • 2022-01-09
      相关资源
      最近更新 更多