美文网首页
Swift - Hashable 和 Equatable 协议

Swift - Hashable 和 Equatable 协议

作者: coderYL | 来源:发表于2017-03-17 16:56 被阅读2671次

    在开发YLLabel过程中,收到这样两个error:

    Type 'YLLabelType' does not conform to protocol 'Hashable'
    Type 'YLLabelType' does not conform to protocol 'Equatable'

    开始不知道为什么会报这个错,后来看了一些资料,写出来,大家多多指教;

    一. Hashable 哈希

    一个类型为了存储在集合中,该类型必须是可哈希化的-该类型必须提供一种方法计算它的哈希值,一个哈希值为Int类型,相等的对象哈希值必须相同。
    Swift的所有基本类型(形如String,Int,Double,Bool)默认是可哈希化的,可以作为集合的值的类型或者字典的键的类型。没有关联值的枚举成员值默认也是可哈希化的。(万幸的是,我用到了枚举关联值,不然我是不知道这些的)

    因为要实现用户自定义高亮类型,所以YLLabelType里提供了这样一个接口
    case custom(pattern:String)
    pattern 是想要匹配的规则

    用户想给自定义的类型添加颜色和点击事件的时候,
    提供了customColor 和 customHandler
    类型是字典, type 作为 key , 颜色和点击事件作为 value
    这时,就提示了上面提到的
    Type 'YLLabelType' does not conform to protocol 'Hashable'
    我们可以看到 协议Hashable是准守了Equatable协议,并且提供了一个需要我们实现 get 方法的属性 hashValue

    public protocol Hashable : Equatable {
    
        /// The hash value.
        ///
        /// Hash values are not guaranteed to be equal across different executions of
        /// your program. Do not save hash values to use during a future execution.
        public var hashValue: Int { get }
    }
    

    我的实现(-3,-2,-1,随手写的,能区分就好吧???求指点)

    extension YLLabelType : Hashable, Equatable{
        public var hashValue : Int {
            switch self {
            case .hashtag   : return -3
            case .mention   : return -2
            case .URL       : return -1
            case .custom(let pattern) : return pattern.hashValue
            }
        }
    }
    

    二. Equatable 判等

    在判等上 Swift 的行为和 Objective-C 有着巨大的差别。在 Objective-C 中 == 这个符号的意思是判断两个对象是否指向同一块内存地址。其实很多时候这并不是我们经常所期望的判等,我们更关心的往往还是对象的内容相同,而这种意义的相等即使两个对象引用的不是同一块内存地址时,也是可以做到的。

    因为YLLabelType加入了case custom(pattern:String)
    所以判等的时候,就需要我们遵循Equatable

    
    public protocol Equatable {
    
        /// Returns a Boolean value indicating whether two values are equal.
        ///
        /// Equality is the inverse of inequality. For any values `a` and `b`,
        /// `a == b` implies that `a != b` is `false`.
        ///
        /// - Parameters:
        ///   - lhs: A value to compare.
        ///   - rhs: Another value to compare.
        public static func ==(lhs: Self, rhs: Self) -> Bool
    }
    
    

    第一眼看到怪怪的,其实就是方法名是==,和普通方法一样了就
    我的实现

    public func == (lhs: YLLabelType, rhs: YLLabelType) -> Bool {
        
        switch (lhs, rhs) {
        case (.mention, .mention): return true
        case (.hashtag, .hashtag): return true
        case (.URL, .URL): return true
        case (.custom(let pattern1), .custom(let pattern2)): 
                           return pattern1 == pattern2
        default: return false
        }
    }
    

    还要多说一点的是
    对于== 的实现我们并没有像实现其他一些协议一样将其放在对应的 extension里,而是放在了全局,因为你应该需要在全局范围内都能使用 ==

    这时候,可能会报一个错

    只要在枚举定义enum前面加上public就可以了

    相关文章

      网友评论

          本文标题:Swift - Hashable 和 Equatable 协议

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