简体   繁体   中英

How to convert UInt16 to UInt8 in Swift 3?

I want to convert UInt16 to UInt8 array, but am getting the following error message:

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

The code:

    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))
    }

As the error message indicates, you have to use withMemoryRebound() to reinterpret the pointer to UInt16 as a pointer to 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)))
    }
}

The closures are invoked with pointers ( $0 ) which are only valid for the lifetime of the closure and must not be passed to the outside for later use. That's why an Array is created and used as return value.

There is a simpler solution however:

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

Explanation: withUnsafeBytes invokes the closure with a UnsafeRawBufferPointer to the storage of the bigEndian variable. Since UnsafeRawBufferPointer is a Sequence of UInt8 , an array can be created from that with Array($0) .

You can extend Numeric protocol and create a data property as follow:

Swift 4 or later

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

Since Swift 3 Data conforms to RandomAccessCollection so you can just create an array of bytes from your UInt16 bigEndian data:

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

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM