Swift的Equatable和Comparable的使用

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Swift的Equatable和Comparable的使用相关的知识,希望对你有一定的参考价值。

参考技术A // Equatable
// 要想得知2个实例是否等价,一般做法是遵守Equatable协议,重载:==运算符
// 与此同时,等价于重载了 != 运算符
// 告诉别人这个可以进行等号运算符进行计算的
struct Point: Equatable
var x: Int, y: Int


var p1 = Point(x: 10, y: 20)
var p2 = Point(x: 11, y: 22)
print(p1 == p2)
print(p1 != p2)
// 如果数值是完全一样的,则是相等的

// Swift为以下类型提供默认的Equatable实现
// 没有关联类型的枚举
// 只拥有遵守Equatable协议关联类型的枚举
// 只拥有遵守Equatable协议存储属性的结构体

// 引用类型比较存储的地址值是否相等(是否引用着同一个对象),使用恒等运算符===、 !==

// Comparable
// score大的比较大,若score相等,age小的比较大
struct Student: Comparable
var age: Int
var score: Int
init(score: Int, age: Int)
self.score = score
self.age = age

static func < (lhs: Student, rhs: Student) -> Bool
(lhs.score < rhs.score) || (lhs.score == rhs.score && lhs.age > rhs.age)

static func > (lhs: Student, rhs: Student) -> Bool
(lhs.score > rhs.score) || (lhs.score == rhs.score && lhs.age > rhs.age)

static func <= (lhs: Student, rhs: Student) -> Bool
!(lhs > rhs)

static func >= (lhs: Student, rhs: Student) -> Bool
!(lhs < rhs)


// 要相比较2个实例的大小,一般做法是:
// 遵守Comparable协议
// 重载相应的运算符
var stu1 = Student(score: 100, age: 20)
var stu2 = Student(score: 98, age: 18)
var stu3 = Student(score: 100, age: 20)
print("___________________________")
print(stu1 > stu2)
print(stu1 >= stu2)
print(stu1 >= stu3)
print(stu1 <= stu3)
print(stu1 > stu2)
print(stu1 >= stu2)

在 Swift 中覆盖 Equatable 和 Hashable

【中文标题】在 Swift 中覆盖 Equatable 和 Hashable【英文标题】:Override Equatable and Hashable in Swift 【发布时间】:2019-06-02 00:07:13 【问题描述】:

有没有办法覆盖 NSManagedObject 的 Equatable?我有一个包含 300k 个对象的 coredata 数据集,我需要根据对象的业务 ID 删除重复项。

// Coredata NSManagedObject
import Foundation
import CoreData

@objc(Business)
public class Business: NSManagedObject 


覆盖错误消息:

【问题讨论】:

相关:***.com/questions/33319959/… 【参考方案1】:

NSManagedObject 已经声明它符合EquatableHashable。无需添加: Equatable

您需要直接在 Business 类中覆盖关联的方法,而不使用扩展。

【讨论】:

需要实现的是==,还是NSObjectProtocol.isEqual(_:)?我永远记不清了【参考方案2】:

既然NSManagedObject已经符合Equatable,那你为什么还要再去符合它呢? :) 只需覆盖== 函数,您就可以开始了!

extension Business 
    static func == (lhs: Business, rhs: Business) -> Bool 
        print("custom equation has been called")
        return lhs.id == rhs.id
    

你可以这样测试:

var b1 = Business()
var b2 = Business()
b1.id = "1"
b2.id = "2"

print("b1 == b2 ? \(b1 == b2)")

打印出来的结果证明你的自定义==函数被调用了。

custom equation has been called
b1 == b2 ? false

【讨论】:

这是无效的。您还需要覆盖func hash(into:) 的实现,否则您将违反Hashable 的约定(即相等的值具有相等的哈希值) Methods and Properties You Must Not Override checkout above 链接,它说你不能在 NSManagedObject 中覆盖 ==。此外,如果您想要独特的结果,这样的事情也会很有用。 developer.apple.com/documentation/coredata/nsfetchrequest/… 通过扩展覆盖方法是不好的做法,因为不清楚将执行什么;原件或扩展件。

以上是关于Swift的Equatable和Comparable的使用的主要内容,如果未能解决你的问题,请参考以下文章

避免 Equatable 和 Hashable 样板,Swift 4.2

Swift,Equatable 协议错误?

通过扩展自动合成 Swift 结构或枚举的 Equatable 一致性

Swift Array firstIndex & Equatable [关闭]

Swift 3:如何编写 Equatable 函数

swift Swift 4.2 User Equatable示例