0

我知道 JSON 密钥没有任何顺序并且可以随机生成,但是没有任何东西阻止我编写这个函数,并且从我的测试来看,这适用于我测试的每个用例。

func ==<T: Encodable> (lhs: T, rhs: T) -> Bool {
   let encoder = JSONEncoder()
   do {
       let leftEncoded = try encoder.encode(lhs)
       let rightEncoded = try encoder.encode(rhs)
       return leftEncoded == rightEncoded
   } catch {
       return false
   }
}

我要解决的问题是为一种类型编写一个函数,该类型具有一个协议的数组,具有大约 20 种不同的实现,我必须实现该==函数而不是快速自动合成。而且我知道我可以切换到JSONSerialization.writeJSONObject选项.sortedKeys以保留键顺序。

这个实现而不是任何其他编写==函数的方法的缺点是什么?

4

2 回答 2

2

答案似乎在您的问题中:“JSON 键没有任何顺序。” 此外,逻辑上相等的两件事可能会以不同的方式编码(例如,如果它们的相等性仅取决于它们的 id)。此外,编码相同值的引用类型可能根本不相等(例如 UIView)。此外,这会产生非常广泛的==重载,使类型检查更加昂贵(+非常昂贵)。

您正在做的是尝试自动符合Equatable可以合成的时间。斯威夫特本可以做到这一点;事实上,在大多数Encodable情况下,Equatable只需添加: Equatable. Swift 团队明确选择在这些情况下不自动符合并强制您在您需要时请求它,因为它并不总是意味着“所有属性都包含相同的位”。当 Swift 团队明确选择避免使用某个功能时,重新添加它很少是一个好主意。

于 2018-10-29T16:18:49.317 回答
0
func ==<T: Codable> (lhs: T, rhs: T) -> Bool {
    let encoder = JSONEncoder()

    guard let lhsData = try? encoder.encode(lhs),
          let rhsData = try? encoder.encode(lhs),
          let left = try? JSONSerialization.jsonObject(with: lhsData) as? [String : Any],
          let right = try? JSONSerialization.jsonObject(with: rhsData) as? [String : Any] else { return false }

    let leftDictionary = left as NSDictionary
    let rightDictionary = right

    return leftDictionary.isEqual(to: rightDictionary)
}
于 2021-02-03T20:26:23.947 回答