每一點進步都是快樂:無處不在的擴展
摘要:extension UnsafeMutableRawBufferPointer { var base: UnsafeMutableRawPointer { return baseAddress。首先,我們需要在調試版本中進行簡單的健全性檢查,以確保不會產生無意義的對齊計算。
作者:Russ Bishop, 原文鏈接 ,原文日期:2018-11-08
譯者:俊東;校對: numbbbbb , WAMaker ;定稿: 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。