問題描述
我想將 UInt16 轉(zhuǎn)換為 UInt8 數(shù)組,但收到以下錯(cuò)誤消息:
I want to convert UInt16 to UInt8 array, but am getting the following error message:
'init' 不可用:使用 'withMemoryRebound(to:capacity:_)'暫時(shí)將內(nèi)存視為另一種布局兼容的類型.
'init' is unavailable: use 'withMemoryRebound(to:capacity:_)' to temporarily view memory as another layout-compatible type.
代碼:
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))
}
推薦答案
如錯(cuò)誤信息所示,你必須使用 withMemoryRebound()
將指向 UInt16
的指針重新解釋為指向 UInt8
的指針:
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)))
}
}
閉包是用指針($0
)調(diào)用的,這些指針只有效在閉包的整個(gè)生命周期內(nèi),不得傳遞給外部供以后使用.這就是創(chuàng)建 Array
并將其用作返回值的原因.
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.
但是有一個(gè)更簡單的解決方案:
There is a simpler solution however:
let bytes = withUnsafeBytes(of: &bigEndian) { Array($0) }
解釋: withUnsafeBytes
調(diào)用帶有 UnsafeRawBufferPointer
的閉包到 bigEndian
變量的存儲.由于 UnsafeRawBufferPointer
是 UInt8
的 Sequence
,因此是一個(gè)數(shù)組可以使用 Array($0)
來創(chuàng)建.
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)
.
這篇關(guān)于如何在 Swift 3 中將 UInt16 轉(zhuǎn)換為 UInt8?的文章就介紹到這了,希望我們推薦的答案對大家有所幫助,也希望大家多多支持html5模板網(wǎng)!