每一點進步都是快樂:無處不在的擴展

做者:Russ Bishop,原文連接,原文日期:2018-11-08 譯者:俊東;校對:numbbbbbWAMaker;定稿:Pancfgit

這篇文章記錄了我所收穫的小驚喜。在 Swift 中寫擴展讓人感受很是天然。github

我認爲 UnsafeMutableRawBufferPointer.baseAddress 是可選項這回事很是不合理。在實踐中它會使代碼變得醜陋。我也不喜歡在分配時指定對齊方式;在大多數平臺上,合理的默認值都是 Int.bitWidth / 8swift

經過擴展,咱們能夠很容易地解決這些問題。這樣的解決方案能像標準庫同樣天然地使用。spa

首先,咱們須要在調試版本中進行簡單的健全性檢查,以確保不會產生無心義的對齊計算。這裏提一個有關正整數的小技巧:一個 2 的 n 次冪數只有一個比特位是有值的。減去 1 時就是把後面的全部比特位設置爲 1,如 8(0b1000)- 1 獲得 7(0b0111)。這兩個數字沒有共同的位,所以按位取與應該產生零。因爲這規律在零上無效,因此須要單獨檢查。.net

extension BinaryInteger {
    var isPositivePowerOf2: Bool {
        @inline(__always)
        get {
            return (self & (self - 1)) == 0 && self != 0
        }
    }
}
複製代碼

讓 allocate 方法默認使用天然整數寬度對齊。設置對齊參數可能有點多餘,不過它幾乎能處理咱們想要存儲在緩衝區中的任何數據。雖然斷言僅在調試環境中有效,但這已經夠應付咱們的使用;已知 Swift 支持的平臺上這個斷言都會是 true。翻譯

extension UnsafeMutableRawBufferPointer {
    static func allocate(byteCount: Int) -> UnsafeMutableRawBufferPointer {
        let alignment = Int.bitWidth / 8
        assert(alignment.isPositivePowerOf2, "expected power of two")
        return self.allocate(byteCount: byteCount, alignment: alignment)
    }
}
複製代碼

最後再提一個點,咱們能夠添加一個隱式強制解包的 base 屬性。調試

extension UnsafeMutableRawBufferPointer {
    var base: UnsafeMutableRawPointer {
        return baseAddress!
    }
}
extension UnsafeRawBufferPointer {
    var base: UnsafeRawPointer {
        return baseAddress!
    }
}
複製代碼

一切如此簡單。code

本文由 SwiftGG 翻譯組翻譯,已經得到做者翻譯受權,最新文章請訪問 swift.ggget

相關文章
相關標籤/搜索