Swift Struct doesn't conform to protocol Equatable?

孤者浪人 提交于 2021-02-06 09:45:06

问题


How do I make a structure conform to protocol "Equatable"?

I'm using 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"
   }

}

When I use "MyStruct", Xcode shows the error:

MyStruct does not conform to protocol "Equatable"

Do you have an idea to make MyStruct conform to protocol?


回答1:


Swift 4.1 (and above) Updated answer:

Starting from Swift 4.1, all you have to is to conform to the Equatable protocol without the need of implementing the == method. See: SE-0185 - Synthesizing Equatable and Hashable conformance.

Example:

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


Keep in mind that the default behavior for the == is to compare all the type properties (based on the example: lhs.id == rhs.id && lhs.value == rhs.value). If you are aiming to achieve a custom behavior (comparing only one property for instance), you have to do it by yourself:

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

At this point, the equality would be based on the id value, regardless of what's the value of value.




回答2:


OK, after lots of searching, it's working...

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
}

My Struct was in a class, so it didn't work.. I moved this Struct out of my class and now it's good :)




回答3:


The issue isn't that the struct is within a class. That is certainly allowable, and there are many instances where you might want to do that. The issue is in the implementation of the Equatable protocol. You have to give a global implementation of == (which you have done), but there is no entity MyStruct....it is ParentClass.MyStruct (if the struct is defined within a parent class). The example below in itself is probably not a good example in this case, but it does show how you can do this if needed.

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

Note: I like to implement Comparable rather than just Equatable, which will allow you to support sorting and other functionality.




回答4:


Class and struct are different. Struct is value type, but class is reference type.

You cannot define struct in class. On the contrary, you cannot define class in struct.

Struct and class both can conform to any protocol including your custom protocol.



来源:https://stackoverflow.com/questions/37541512/swift-struct-doesnt-conform-to-protocol-equatable

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!