【问题标题】:How to convert UInt16 to UInt8 in Swift 3?如何在 Swift 3 中将 UInt16 转换为 UInt8?
【发布时间】:2017-11-05 12:56:37
【问题描述】:
我想将 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))
}
【问题讨论】:
标签:
swift
type-conversion
uint16
uint8array
【解决方案1】:
如错误消息所示,您必须使用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 是UInt8 的Sequence,所以是一个数组
可以使用 Array($0) 从中创建。
【解决方案2】:
您可以扩展 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]