我知道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
来保持按键顺序。
此实现的弊端是什么,而不是其他任何编写==
函数的方法?
答案 0 :(得分:2)
答案似乎在您的问题中:“ JSON密钥没有任何顺序。”同样,在逻辑上相等的两个事物可能会编码不同(例如,如果相等性仅取决于其id)。同样,编码相同值的引用类型可能根本无法等同(例如UIView)。而且,这会产生非常广泛的mkdir .docker
重载,这会使类型检查更加昂贵(就像==
极其昂贵)。
您正在做的是尝试在可以合成时自动符合+
。斯威夫特本可以做到的;实际上,对于大多数Equatable
情况,只需添加Encodable
就可以合成Equatable
。在这种情况下,Swift团队明确选择不自动整合,并在您要表达的意思时强制您请求它,因为它并不总是意味着“所有属性都包含相同的位”。当Swift团队明确选择避免使用某个功能时,重新添加该功能几乎不是一个好主意。
答案 1 :(得分: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)
}