一方が他方の負の値である場合、2 つの Decimals を hashValue で区別できないことがわかりました。Decimals を構造体のフィールドとして使用し、その構造体は Hashable を実装してセットに入れることができるようにします。ビジネス ロジックでは、すべてのフィールドが一意である必要があるため、すべてのフィールドと組み合わせて hashValue を指定します。つまり、10 進数フィールドが他方の負の値であり、残りのフィールドが実際に等しい 2 つの構造体は、構造体全体が等しいと見なされます。これは私たちが望んでいるものではありません。
遊び場コード:
for i in 0..<10 {
let randomNumber: Int = Int.random(in: 0..<10000000)
let lhs = Decimal(integerLiteral: randomNumber)
let rhs = Decimal(integerLiteral: -randomNumber)
print("Are \(lhs) and \(rhs)'s hashValues equal? \(lhs.hashValue == rhs.hashValue)")
print("Are \(randomNumber) and \(-randomNumber)'s hashValues equal? \(randomNumber.hashValue == (-randomNumber).hashValue)\n")
}
doubleLiteral
の代わりに を使用してテストする場合も同じことが起こりintegerLiteral
ます。
回避策は、Decimals を直接比較し、必要に応じて、他の部分で必要な場合は hashValue に含めることです。
この動作は意図したものですか? 仮数部は同じなので、等しいと見なされないのは、Decimal の hashValue に符号が含まれていないためだと思いますか?