亮劍吧!枚舉哈希值及選項集

作者:Russ Bishop,原文鏈接,原文日期:2016-11-07
譯者:星夜暮晨;校對:walkingway;定稿:CMB

最近幾天,我在 Swift 用戶列表中參與了一個討論,主題是怎樣才能更好滴將包含字符串值的 JSON 數組轉換為枚舉集 (Enumeration Set)。我半開玩笑地建議:這些字符串值應該被轉換到基于字符串的枚舉當中,然后這些值的 hashValues 將用于設置標志位(flags)。

當然,我很快(并且理所應當)被質疑道:『最終的解決方案是否應該取決于 hashValue 的實現細節』—— 很顯然不應該。但是隨著我思考的深入,我猜想是否可以通過哈希值來引導選項集 (Option Sets) 的創建,從而消除潛在的錯誤呢?

我的意思是假設有這樣一個枚舉:

private enum LaundryFlags: String { 
  case lowWater, lowHeat, gentleCycle, tumbleDry
}

我們可以使用枚舉值來生成選項集,因為我們知道每個 hashValue 都不會發生重疊,這使得編譯器可以自行選擇實現的細節,而不用人工干涉:

public static let lowWater = LaundryOptions(rawValue: 
    1 << LaundryFlags.lowWater.hashValue)

這個方法讓我們可以從字符串中構建選項集,而無需關注具體的原始值 (Raw Value)。無論編譯器如何計算,最終的結果都是一致的:

// 基于字符串的初始化操作
public init(strings: [String]) {
  let set: LaundryOptions = strings
    .flatMap({ LaundryFlags(rawValue: $0) }) // 轉換為枚舉
    .map({ 1 << $0.hashValue }) // 轉換為 Int,即標志值
    .flatMap({ LaundryOptions(rawValue: $0) }) // 轉換為選項集
    .reduce([]) { $0.union($1) } // 聯結
  _rawValue = set.rawValue
}

不過這種做法也有限制。我們無法使用枚舉來表示如下所示的復合便利成員 (Compound Convenience Members):

public static let energyStar: LaundryOptions = [.lowWater, .lowHeat]
public static let gentleStar: LaundryOptions = energyStar.union(gentleCycle)

此外,我們可以很容易地實現 CustomStringConvertible 協議,即便原始值枚舉無法顯示它們的成員,并且也無法使用哈希值來進行初始化。如下面這段代碼所示,生成一個延遲成員 (Lazy Member) 字典并不困難。我們可以將這個實現變為樣板代碼 (Boiler Plate),然后將您的案例清單 (Case List) 復制/粘貼到這個數組當中:

static var memberDict: Dictionary<Int, String> = 
    [lowWater, lowHeat, gentleCycle, tumbleDry]
    .reduce([:]) {
        var dict = $0
        dict[$1.hashValue] = "\($1)" 
        return dict
    }

通過位運算,我們便可以從選項集當中規約 (Reduce) 出這個字典:

public var description: String {
    let members = LaundryFlags.memberDict.reduce([]) {
        return (rawValue & 1 << $1.key) != 0
            ? $0 + [$1.value] : $0
    }
    return members.joined(separator: ", ")
}

所以讓我們亮劍吧:考慮到這個方法是多么地簡單可靠,那我還能繼續遵循『原始值枚舉以及它們的哈希值從不使用實現細節』的約定么?

完整的 gist 代碼可在此查看

本文由 SwiftGG 翻譯組翻譯,已經獲得作者翻譯授權,最新文章請訪問 http://swift.gg

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容