比较匹配器在混合数字类型上失败

Comparison matchers fail on mixed numeric types

在 vanilla Scala 中,以下断言通过

assert(1D > 0F)
assert(1F > 0)
assert(1L > 0)
assert(1 > 0.toShort)
assert(1.toShort > 0.toChar)

然而 ScalaTest 中的相似匹配器 fail

1D shouldBe > (0F)
1F shouldBe > (0)
1L shouldBe > (0)
1 shouldBe > (0.toShort)
1.toShort shouldBe > (0.toChar)

解决方法是让两边的类型相同,例如

1D shouldBe > (0D)

为什么它在 Scala 中有效,但在 Scalatest 中无效,或者 >

的签名是什么
def >[T : Ordering] (right: T): ResultOfGreaterThanComparison[T]

这让它失败了?

Vanilla Scala 由于自动类型转换而工作,即 0F 被转换为 0D,这是许多语言的常见做法。

更有趣的问题是为什么shouldBe不起作用。 De-sugaring 隐式产生

new AnyShouldWrapper[Double](leftSideValue = 1D,
                             pos = ???,
                             prettifier = ???)
  .shouldBe(new ResultOfGreaterThanComparison[Double](right = 0D))

new AnyShouldWrapper[Double](leftSideValue = 1D,
                             pos = ???,
                             prettifier = ???)
  .shouldBe(new ResultOfGreaterThanComparison[Float](right = 0F))

这会导致 shouldBe 的重载实现。前一种情况 here and the latter here.

查看源代码后,似乎 1D shouldBe > (0F) 实际编译的唯一原因是支持使用 shouldBe 关键字进行数组比较。