我想将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))
}
答案 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
变量存储的闭包。
由于UnsafeRawBufferPointer
是Sequence
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]