【问题标题】:Deep compare arrays in tuples in ScalaScala中元组中的深度比较数组
【发布时间】:2015-03-30 16:51:29
【问题描述】:

作为一些测试的一部分,我试图在 Scala 中比较包含数组的元组,但遇到了一个问题,它似乎比较的是数组对象而不是内容。

比较数组本身可以正常工作;这通过了:

assertResult(Array[Byte](0.toByte, 2.toByte))(Array[Byte](0.toByte, 2.toByte))

但是,当我将数组放入一个元组中并与 long 配对时,我得到了一个异常

这是测试代码:

assertResult((12345678L, Array[Byte](0.toByte, 2.toByte)))((12345678L, Array[Byte](0.toByte, 2.toByte)))

我得到的例外是:

org.scalatest.exceptions.TestFailedException: Expected (12345678,[B@2473d930), but got (12345678,[B@35047d03)

从它打印出数组的内存位置的方式来看,它让我觉得它是在比较对象引用,而不是深入比较数组中的每个对象。

这是在 Scala 中预期的,还是我在这里做错了什么? 感谢阅读。

【问题讨论】:

    标签: scala


    【解决方案1】:

    如果您在Arrays 上致电deep,它将起作用:

    assertResult((12345678L, Array[Byte](0.toByte, 2.toByte).deep))((12345678L, Array[Byte](0.toByte, 2.toByte).deep))
    

    这实际上只是将Array 转换为IndexedSeq,因此它可以进行equals 比较(而不是Array 上的默认参考比较)。如果顶级比较是Array,似乎assertResult 会为您执行此操作,但如果Array 嵌套在另一个对象中则不会。这就是第一个示例有效,而第二个无效的原因。

    鉴于此,这样做可能非常不方便,您可能会考虑使用 Array 以外的其他集合类型。

    【讨论】:

    • 我明白了,谢谢。那么,如果我有一些东西可以返回已经形成的此类元组的 Iterable,那么我唯一的选择是遍历它们并在每个数组上调用 .deep 吗?
    • 可能,是的。我认为测试框架不够聪明,无法看那么深。
    【解决方案2】:

    这是正确的,根据 Java 的数组相等(或缺乏)行为。

    从消息 ([B@2473d930) 中可以看出,Scala Array 类型是 Java 数组的精美外观;但它不能改变 Java 数组实例的实际工作方式。

    最直接的解决方案可能是使用正确实现==(又名Object.equals)的集合类型。

    Tuple1(Array(1)) == Tuple1(Array(1))  // false
    Tuple1(List(1)) == Tuple1(List(1))    // true
    

    (请参阅 m-z 的答案,了解为什么非嵌套案例有效。)

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-10-20
      • 1970-01-01
      • 2016-09-01
      • 2017-01-19
      • 1970-01-01
      • 2022-01-10
      • 2020-08-13
      • 2011-07-20
      相关资源
      最近更新 更多