我引用this。
我是ScalaTest的新手,但我认为这意味着,如果我实施了==
,那么这将用于解释should equal
。但是,我的代码似乎与此相矛盾。
我正在通过Odersky's book - 我正在练习6.0.3。我已经实现了如上所述的自然数,并添加了相等运算符:
class Succ(x: Nat) extends Nat {
...
override def ==(that:Nat): Boolean = {
try {
(that - this).isZero
} catch {
case _: Throwable => false
}
}
}
object Zero extends Nat {
...
override def ==(that:Nat): Boolean = {
that.isZero
}
}
但是,以下测试用例失败:
def makeNat(n:Integer):Nat = {
if (n < 0) throw new RuntimeException("Can't generate Nat from <0: " + n.toString())
if (n==0) return Zero
else return makeNat(n-1).suc
}
test("Addition is commutative") {
val nats = for (n <- Gen.choose(0, 1000)) yield makeNat(n)
val p = forAll ((nats, "n1"), (nats, "n2")) {
(n1: Nat, n2: Nat) =>
(n1 + n2) should equal (n2 + n1) //Fails
}
}
但是减去参数并与Zero通过比较:
test("Addition is commutative") {
val nats = for (n <- Gen.choose(0, 1000)) yield makeNat(n)
val p = forAll ((nats, "n1"), (nats, "n2")) {
(n1: Nat, n2: Nat) =>
((n1 + n2)-(n2+n1)) should equal (Zero) // Passes
}
}
编辑:感谢dwickern @,这已经解决了 - 我需要为equals
方法添加覆盖,而不是==
方法。即:
override def equals(that:Any): Boolean = that match {
case that:Nat => (that-this).isZero
case _ => false
}
答案 0 :(得分:3)
如您所知,您需要覆盖equals
而不是==
。 scala中的==
方法调用Java的标准Object.equals
,除非它正确处理null而不抛出异常。
在实践中,您不需要经常覆盖equals
因为存在案例类。要使用它们,请将class
更改为case class
,将object
更改为case object
。编译器将为您实现equals
和hashCode
。如果一个类遵循这些模式,则案例类非常适合: