26

如何使结构符合“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 符合协议的想法吗?

4

4 回答 4

40

Swift 4.1(及更高版本)更新答案:

从 Swift 4.1 开始,你所要做的就是遵守Equatable协议而不需要实现==方法。请参阅:SE-0185 - 综合 Equatable 和 Hashable 一致性

例子:

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

此时,相等性将基于id值,而不管 的值是多少value

于 2018-07-11T07:55:23.403 回答
23

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

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
}

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

于 2016-05-31T09:23:15.023 回答
8

问题不在于结构在一个类中。这当然是允许的,在很多情况下您可能想要这样做。问题在于 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,这将允许您支持排序和其他功能。

于 2016-05-31T13:17:51.900 回答
-3

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

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

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

于 2016-05-31T09:34:31.850 回答