【问题标题】:Swift Struct doesn't conform to protocol Equatable?Swift Struct 不符合 Equatable 协议?
【发布时间】:2016-09-29 05:15:19
【问题描述】:

如何使结构符合“Equatable”协议?

我使用的是 Xcode 7.3.1

struct MyStruct {
   var id: Int
   var value: String

   init(id: Int, value: String) {
       self.id = id
       self.value = value
   }

   var description: String {
       return "blablabla"
   }

}

当我使用“MyStruct”时,Xcode 显示错误:

MyStruct 不符合“Equatable”协议

你有让 MyStruct 符合协议的想法吗?

【问题讨论】:

    标签: swift struct protocols equatable


    【解决方案1】:

    Swift 4.1(及以上)更新答案:

    从 Swift 4.1 开始,您只需遵守 Equatable 协议即可,无需实现 == 方法。见:SE-0185 - Synthesizing Equatable and Hashable conformance。

    例子:

    struct MyStruct: Equatable {
        var id: Int
        var value: String
    }
    
    let obj1 = MyStruct(id: 101, value: "object")
    let obj2 = MyStruct(id: 101, value: "object")
    
    obj1 == obj2 // true
    


    请记住== 的默认行为是比较所有类型属性(基于示例:lhs.id == rhs.id && lhs.value == rhs.value)。如果您的目标是实现自定义行为(例如仅比较一个属性),则必须自己完成:

    struct MyStruct: Equatable {
        var id: Int
        var value: String
    }
    
    extension MyStruct {
        static func ==(lhs: MyStruct, rhs: MyStruct) -> Bool {
            return lhs.id == rhs.id
        }
    }
    
    let obj1 = MyStruct(id: 101, value: "obj1")
    let obj2 = MyStruct(id: 101, value: "obj2")
    
    obj1 == obj2 // true
    

    此时,无论value 的值是什么,均等性将基于id 的值。

    【讨论】:

    • 这将是大多数有此问题的人的正确答案。
    【解决方案2】:

    类和结构是不同的。 struct是值类型,class是引用类型。

    你不能在类中定义结构。相反,你不能在struct中定义类。

    结构和类都可以符合任何协议,包括您的自定义协议。

    【讨论】:

      【解决方案3】:

      好的,经过大量搜索,它正在工作......

      struct MyStruct {
          var id: Int
          var value: String
      
          init(id: Int, value: String) {
              self.id = id
              self.value = value
          }
      
          var description: String {
              return "blablabla"
          }
      
      }
      
      extension MyStruct: Equatable {}
      
      func ==(lhs: MyStruct, rhs: MyStruct) -> Bool {
          let areEqual = lhs.id == rhs.id &&
              lhs.value == rhs.value
      
          return areEqual
      }
      

      我的结构在课堂上,所以它不起作用..我把这个结构移出我的课堂,现在它很好:)

      【讨论】:

      • 见 DJohnson 的回答:上课不是问题
      【解决方案4】:

      问题不在于结构在一个类中。这当然是允许的,在很多情况下您可能想要这样做。问题在于 Equatable 协议的实现。您必须提供 == 的全局实现(您已经完成了),但是没有实体 MyStruct ....它是 ParentClass.MyStruct (如果结构是在父类中定义的)。在这种情况下,下面的示例本身可能不是一个很好的示例,但它确实显示了如果需要,您可以如何做到这一点。

      class ParentClass {
      
        struct MyStruct {
          var id: Int
          var value: String
      
          init(id: Int, value: String) {
            self.id = id
            self.value = value
          }
      
          var description: String {
            return "blablabla"
          }
        }
      }
      
      extension ParentClass.MyStruct: Equatable {}
      
      func ==(lhs: ParentClass.MyStruct, rhs: ParentClass.MyStruct) -> Bool {
        let areEqual = lhs.id == rhs.id &&
          lhs.value == rhs.value
      
        return areEqual
      }
      
      let s1 = ParentClass.MyStruct(id: 1, value: "one")
      let s2 = ParentClass.MyStruct(id: 2, value: "two")
      let s3 = ParentClass.MyStruct(id: 1, value: "one")
      
      s1.description    //blablabla
      
      s1 == s2         //false
      s3 == s1         //true
      

      注意:我喜欢实现 Comparable 而不仅仅是 Equatable,这将允许您支持排序和其他功能。

      【讨论】:

      • 如何做通用的?这样我就可以在我的所有班级和结构中使用它
      猜你喜欢
      • 1970-01-01
      • 2017-06-27
      • 1970-01-01
      • 1970-01-01
      • 2020-12-04
      • 1970-01-01
      • 2016-06-07
      • 2015-11-02
      相关资源
      最近更新 更多