摘要:extension UnsafeMutableRawBufferPointer { var base: UnsafeMutableRawPointer { return baseAddress。首先,我們需要在調試版本中進行簡單的健全性檢查,以確保不會產生無意義的對齊計算。

作者:Russ Bishop, 原文鏈接 ,原文日期:2018-11-08

譯者:俊東;校對: numbbbbbWAMaker ;定稿: Pancf

這篇文章記錄了我所收穫的小驚喜。在 Swift 中寫擴展讓人感覺非常自然。

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

通過擴展,我們可以很容易地解決這些問題。這樣的解決方案能像標準庫一樣自然地使用。

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

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!
    }
}

一切如此簡單。

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

相關文章