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

时间:2017-06-04 18:08:59

标签: swift type-conversion uint16 uint8array

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

  

'init'不可用:使用'withMemoryRebound(to:capacity:_)'来   暂时将内存视为另一种与布局兼容的类型。

代码:

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

    var bigEndian = lenghtByte.bigEndian

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

2 个答案:

答案 0 :(得分:7)

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

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

使用仅有效的指针($0)调用闭包 关闭的一生,不得传递到外面 供以后使用。这就是创建Array并将其用作返回值的原因。

然而,有一个更简单的解决方案:

let bytes = withUnsafeBytes(of: &bigEndian) { Array($0) }

说明: withUnsafeBytes使用UnsafeRawBufferPointer调用bigEndian变量存储的闭包。 由于UnsafeRawBufferPointerSequence UInt8,因此是一个数组 可以使用Array($0)创建。

答案 1 :(得分:4)

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

Swift 4或更高版本

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

由于Swift 3 Data符合RandomAccessCollection,因此您只需从UInt16 bigEndian数据中创建一个字节数组:

extension Data {
    var array: [UInt8] { return Array(self) }
}
let lenghtByte = UInt16(8)
let bytePtr = lenghtByte.bigEndian.data.array   // [0, 8]