每一点进步都是快乐:无处不在的扩展

做者: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

相关文章
相关标签/搜索