在Swift中使用JSONECODER实现均衡方法
我知道JSON键没有任何顺序,可以随机生成,但是没有任何东西阻止我编写这个函数,从我的测试来看,这在我测试的每个用例上都有效在Swift中使用JSONECODER实现均衡方法,swift,codable,equatable,encodable,Swift,Codable,Equatable,Encodable,我知道JSON键没有任何顺序,可以随机生成,但是没有任何东西阻止我编写这个函数,从我的测试来看,这在我测试的每个用例上都有效 func ==<T: Encodable> (lhs: T, rhs: T) -> Bool { let encoder = JSONEncoder() do { let leftEncoded = try encoder.encode(lhs) let rightEncoded = try encoder.enc
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
}
}
func==(左:T,右:T)->Bool{
let encoder=JSONEncoder()
做{
leftEncoded=尝试编码器.encode(lhs)
let rightEncoded=尝试编码器.encode(rhs)
返回leftEncoded==rightEncoded
}抓住{
返回错误
}
}
我想解决的问题是为一个类型编写一个函数,该类型有一个协议数组,有20种不同的实现,我必须实现
==
函数,而不是swift自动合成。我知道我可以切换到JSONSerialization.writeJSONObject
,使用选项.sortedKeys
,以保持键顺序
这个实现代替任何其他编写函数的方法有什么缺点?答案似乎在你的问题中:“JSON键没有任何顺序。”此外,逻辑上相等的两个东西可能编码不同(例如,如果它们的相等性仅取决于它们的id)。此外,编码相同值的引用类型可能根本不相等(例如UIView)。此外,这会创建一个非常广泛的
==
重载,使类型检查更加昂贵(就像+
非常昂贵一样)
您所做的是尝试在可以合成时自动符合
equalable
。斯威夫特本可以做到这一点;事实上,对于大多数可编码的
情况,可均衡的
可以通过添加:可均衡的
来合成。在这些情况下,Swift团队明确选择不自动符合,并在您有意时强制您请求,因为这并不总是意味着“所有属性都包含相同的位”。当Swift团队明确选择避免某个功能时,重新添加它很少是一个好主意。答案似乎在您的问题中:“JSON键没有任何顺序。”此外,逻辑上相等的两个东西可能编码不同(例如,如果它们的相等性仅取决于它们的id)。此外,编码相同值的引用类型可能根本不相等(例如UIView)。此外,这会创建一个非常广泛的==
重载,使类型检查更加昂贵(就像+
非常昂贵一样)
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)
}
您所做的是尝试在可以合成时自动符合Equatable
。Swift本可以做到这一点;事实上,对于大多数可编码的
情况,只需添加:Equatable
,就可以合成Equatable
。Swift团队明确选择在这些情况下不自动符合,并强制您重新请求因为它并不总是意味着“所有属性都包含相同的位”。当Swift团队明确选择避免某个功能时,重新添加它很少是一个好主意。func==(lhs:t,rhs:t)->Bool{
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)
}
let encoder=JSONEncoder()
guard let lhsData=try?编码器.encode(lhs),
设rhsData=try?编码器.encode(lhs),
left=try?JSONSerialization.jsonObject(带:lhsData)为?[String:Any],
let right=try?JSONSerialization.jsonObject(with:rhsData)作为?[String:Any]else{return false}
让leftDictionary=左为NSDictionary
让rightDictionary=right
返回leftDictionary.isEqual(到:rightDictionary)
}
func==(左:T,右:T)->Bool{
let encoder=JSONEncoder()
guard let lhsData=try?编码器.encode(lhs),
设rhsData=try?编码器.encode(lhs),
left=try?JSONSerialization.jsonObject(带:lhsData)为?[String:Any],
let right=try?JSONSerialization.jsonObject(with:rhsData)作为?[String:Any]else{return false}
让leftDictionary=左为NSDictionary
让rightDictionary=right
返回leftDictionary.isEqual(到:rightDictionary)
}
将对象加密为JSON,然后比较两个编码的数据
对象似乎是一种不必要的开销,因为您可以简单地使T
符合equalatable
,特别是因为Swift 4.1可以自动合成大多数类型的equalatable
一致性。return try JSONEncoder().encode(lhs)==JSONEncoder().encode(rhs)
@LeoDabus,这将使此函数抛出。@RobNapier我没有说要删除do catch
do{return try JSONEncoder().encode(lhs)==JSONEncoder().encode(rhs}catch{print(error)return false}
将对象加密为JSON,然后比较两个编码的数据
对象似乎是一种不必要的开销,因为您可以简单地使T
符合equalatable
,特别是因为Swift 4.1可以自动合成大多数类型的equalatable
一致性。return try JSONEncoder().encode(lhs)==JSONEncoder().encode(rhs)
@LeoDabus,这将使此函数抛出。@RobNapier我没有说要删除do catch
do{return try JSONEncoder().encode(lhs)==JSONEncoder().encode(rhs}catch{print(error)return false}
我想解决的问题是为一种类型编写一个函数,这种类型有一个协议数组,有20种不同的实现方式,我必须实现=
函数,而不是快速自动合成。我知道我可以切换到JSONSerialization.writeJSONObject
选项。sortedKeys
到pers列出密钥顺序。您提到了函数的重载,它是用于编译时还是用于运行时?将此描述添加到问题中这是编译时问题。通过将其附加到协议类型而不是所有En,您可以实现上述目标,而不会产生意外的副作用