在開發(fā)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)默認是可哈献艴耍化的闰挡,可以作為集合的值的類型或者字典的鍵的類型。沒有關聯(lián)值的枚舉成員值默認也是可哈嫌拱化的解总。(萬幸的是,我用到了枚舉關聯(lián)值,不然我是不知道這些的)
因為要實現(xiàn)用戶自定義高亮類型,所以YLLabelType
里提供了這樣一個接口
case custom(pattern:String)
pattern 是想要匹配的規(guī)則
用戶想給自定義的類型添加顏色和點擊事件的時候,
提供了customColor 和 customHandler
類型是字典, type 作為 key , 顏色和點擊事件作為 value
這時,就提示了上面提到的
Type 'YLLabelType' does not conform to protocol 'Hashable'
我們可以看到 協(xié)議Hashable是準守了Equatable協(xié)議,并且提供了一個需要我們實現(xiàn) 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 }
}
我的實現(xiàn)(-3,-2,-1,隨手寫的,能區(qū)分就好吧???求指點)
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
}
第一眼看到怪怪的,其實就是方法名是==,和普通方法一樣了就
我的實現(xiàn)
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
}
}
還要多說一點的是
對于==
的實現(xiàn)我們并沒有像實現(xiàn)其他一些協(xié)議一樣將其放在對應的 extension
里,而是放在了全局,因為你應該需要在全局范圍內都能使用 ==
這時候,可能會報一個錯
只要在枚舉定義enum前面加上public就可以了