Swift Struct不符合协议Equatable?

Ins*_*sou 18 struct protocols swift equatable

如何使结构符合协议"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"
   }

}
Run Code Online (Sandbox Code Playgroud)

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

MyStruct不符合协议"Equatable"

你有想法使MyStruct符合协议吗?

Ahm*_*d F 26

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

从Swift 4.1开始,您只需遵守Equatable协议而无需实现该==方法.请参阅:SE-0185 - 合成等同和可灌输的一致性.

例:

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
Run Code Online (Sandbox Code Playgroud)


请记住,默认行为==是比较所有类型属性(基于示例:) 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
Run Code Online (Sandbox Code Playgroud)

在这一点上id,无论价值是多少,相等都将基于价值value.


Ins*_*sou 18

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

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
}
Run Code Online (Sandbox Code Playgroud)

我的结构是在一个类中,所以它没有用.我把这个Struct移出了我的班级,现在它很好:)

  • 请参阅 DJohnson 的回答:上课不是问题 (2认同)

DJo*_*son 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
Run Code Online (Sandbox Code Playgroud)

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