美文网首页Swift
swift Equatable

swift Equatable

作者: tom__zhu | 来源:发表于2022-05-29 01:10 被阅读0次

    我来了,swift

    定义

    用于做值类型对比的协议。

    适用范围

    遵循Equatable的类型都可以使用==或是!=符号对比判断。这个类型包括struct/class/enum

    实现原理

    任何遵循Equatable的类型,都需要实现方法static func ==(lhs: Self, rhs: Self) -> Bool在这个方法内按照指定的值和值间对比关系返回true或是false,外部表现为==或是!=的结果

    struct Human: Equatable {
        var name: String
        var age = 5
        
        static func == (lhs: Self, rhs: Self) -> Bool {
            return lhs.name == rhs.name
        }
    }
    
    let tom = Human(name: "tom", age: 5)
    let tim = Human(name: "tim", age: 6)
    tom == tim // false
    
    let man1 = Human(name: "tom", age: 5)
    let man2 = Human(name: "tom", age: 6)
    man1 == man2 // true
    

    Human对Equatable方法定义为只判断name属性是否值相同,即使age属性不同,man1==man2结果是true

    在不同类型中的差异

    • class遵循Equatable必须要实现static func ==(lhs: Self, rhs: Self) -> Bool方法。但是,struct遵循Equatable可以不用实现static func ==(lhs: Self, rhs: Self) -> Bool方法,默认将struct实例中所有属性对比并返回结果
    struct Dog: Equatable {
        var name: String
        var age = 0
    }
    
    let dog1 = Dog(name: "tom", age: 1)
    let dog2 = Dog(name: "tom", age: 1)
    dog1 == dog2  // true
    
    let dog3 = Dog(name: "tom", age: 1)
    let dog4 = Dog(name: "tom", age: 2)
    dog3 == dog4  // false
    

    struct Dog遵循Equatable协议但没有实现协议方法其实例dog1与dog2实例相等,dog3与dog3实例不相等

    • 数组等容器类(数组/字典等)内部的元素需要遵循Equatable才能实现一些能力,例如contains(_:)
    let students = ["Kofi", "Abena", "Efua", "Kweku", "Akosua"]
    
    let nameToCheck = "Kofi"
    if students.contains(nameToCheck) {
        print("\(nameToCheck) is signed up!")  // Prints "Kofi is signed up!"
    } else {
        print("No record of \(nameToCheck).")
    }
    
    
    • swift standard library中的大部分基础类型默认已经遵循Equatable,例如Int/Array/Dictionary/Set
    • struct重的属性如果有不遵守Equatable,那么其实例无法用==
    class MyClassNoEquatable {
        
    }
    
    struct NoEquatableStruct: Equatable {
        var mc = MyClassNoEquatable()
        
    }
    
    let nes1 = NoEquatableStruct()
    let nes2 = NoEquatableStruct()
    nes1 == nes2
    

    上面代码会报错,提示Type 'NoEquatableStruct' does not conform to protocol 'Equatable'

    协议间的关联

    Hashable协议基于Equatable协议,对于struct遵守Hashable并不需要实现Equatable方法,但是对于class遵守Hashable必须要实现Equatable的方法
    Comparable协议基于Equatable

    =====

    • Equatable本质是对属性的值对比,适用范围有struct/class/enum
    • ===是对class实例指针的对比,且仅适用于class实例
    class IntegerRef: Equatable {
        let value: Int
        init(_ value: Int) {
            self.value = value
        }
    
        static func == (lhs: IntegerRef, rhs: IntegerRef) -> Bool {
            return lhs.value == rhs.value
        }
    }
    let a = IntegerRef(100)
    let b = IntegerRef(100)
    
    print(a == a, a == b, separator: ", ") // Prints "true, true"
    
    let c = a
    print(c === a, c === b, separator: ", ") // Prints "true, false"
    
    

    参考

    Equatable
    Swift Equatable

    相关文章

      网友评论

        本文标题:swift Equatable

        本文链接:https://www.haomeiwen.com/subject/fmtwprtx.html