Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/video/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在Swift中使用JSONECODER实现均衡方法_Swift_Codable_Equatable_Encodable - Fatal编程技术网

在Swift中使用JSONECODER实现均衡方法

在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

我知道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
   }
}
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,您可以实现上述目标,而不会产生意外的副作用