如何在 Swift 3 中将 UInt16 转换为 UInt8?

How to convert UInt16 to UInt8 in Swift 3?

我想将 UInt16 数组转换为 UInt8 数组,但收到以下错误消息:

'init' is unavailable: use 'withMemoryRebound(to:capacity:_)' to temporarily view memory as another layout-compatible type.

代码:

    let statusByte: UInt8 = UInt8(status)
    let lenghtByte: UInt16 = UInt16(passwordBytes.count)

    var bigEndian = lenghtByte.bigEndian

    let bytePtr = withUnsafePointer(to: &bigEndian) {
        UnsafeBufferPointer<UInt8>(start: UnsafePointer([=11=]), count: MemoryLayout.size(ofValue: bigEndian))
    }

您可以扩展 Numeric 协议并创建数据 属性,如下所示:

Swift 4 或更高版本

extension Numeric {
    var data: Data {
        var source = self
        return Data(bytes: &source, count: MemoryLayout<Self>.size)
    }
}

因为 Swift 3 数据符合 RandomAccessCollection 所以你可以从你的 UInt16 bigEndian 数据创建一个字节数组:

extension Data {
    var array: [UInt8] { return Array(self) }
}

let lenghtByte = UInt16(8)
let bytePtr = lenghtByte.bigEndian.data.array   // [0, 8]

如错误消息所示,您必须使用 withMemoryRebound() 将指向 UInt16 的指针重新解释为指向 UInt8 的指针:

let bytes = withUnsafePointer(to: &bigEndian) {
    [=10=].withMemoryRebound(to: UInt8.self, capacity: MemoryLayout.size(ofValue: bigEndian)) {
        Array(UnsafeBufferPointer(start: [=10=], count: MemoryLayout.size(ofValue: bigEndian)))
    }
}

闭包是用指针 ([=15=]) 调用的,这些指针仅有效 在闭包的生命周期内,不得传递给外部 供以后使用。这就是创建 Array 并将其用作 return 值的原因。

但是有一个更简单的解决方案:

let bytes = withUnsafeBytes(of: &bigEndian) { Array([=11=]) }

解释: withUnsafeBytes 调用带有 UnsafeRawBufferPointer 的闭包到 bigEndian 变量的存储。 由于 UnsafeRawBufferPointerUInt8Sequence,一个数组 可以从 Array([=23=]).

创建