做者:Russ Bishop,原文连接,原文日期:2018-11-08 译者:俊东;校对:numbbbbb,WAMaker;定稿:Pancfgit
这篇文章记录了我所收获的小惊喜。在 Swift 中写扩展让人感受很是天然。github
我认为 UnsafeMutableRawBufferPointer.baseAddress
是可选项这回事很是不合理。在实践中它会使代码变得丑陋。我也不喜欢在分配时指定对齐方式;在大多数平台上,合理的默认值都是 Int.bitWidth / 8
。swift
经过扩展,咱们能够很容易地解决这些问题。这样的解决方案能像标准库同样天然地使用。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.gg。get