Как конвертировать UInt16 в UInt8 в Swift 3?

Я хочу преобразовать UInt16 в массив UInt8, но получаю следующее сообщение об ошибке:

'init' недоступен: используйте 'withMemoryRebound(to:acity:_)', чтобы временно просмотреть память как другой тип, совместимый с макетом.

Код:

    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 ответа

Решение

Как указывает сообщение об ошибке, вы должны использовать 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 переменная. поскольку UnsafeRawBufferPointer это Sequence из UInt8из этого можно создать массив Array($0),

Вы можете расширить числовой протокол и создать свойство данных следующим образом:

Swift 4 или позже

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

Поскольку Swift 3 Data соответствует RandomAccessCollection так что вы можете просто создать массив байтов из ваших данных bigIndian UInt16:

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

let lenghtByte = UInt16(8)
let bytePtr = lenghtByte.bigEndian.data.array   // [0, 8]
Другие вопросы по тегам