如何在 Swift 中将 Floats 的 ContiguousArray 转换为字节数组?
Posted
技术标签:
【中文标题】如何在 Swift 中将 Floats 的 ContiguousArray 转换为字节数组?【英文标题】:How to convert an ContiguousArray of Floats into a byte array in Swift? 【发布时间】:2019-11-21 18:25:26 【问题描述】:我试图在 Swift 中将 Floats 的 ContiguousArray 转换为字节数组,但如果不使用 for 循环就找不到聪明的方法。我一直在关注以前的帖子,例如How to convert a double into a byte array in swift?,但是如果不逐个迭代地获取每个元素,我就无法检索数组的内容。
有没有一种优雅的方法可以直接将 ContiguousArray 的字节直接“复制”到字节数组?
PS:我已经成功实现了将结构转换为字节数组,但不能对数组做同样的事情。
【问题讨论】:
您能否编辑您的帖子并显示所需的输入和输出 【参考方案1】:您可以使用withUnsafeBytes()
方法获取指向数组连续存储的底层字节的缓冲区指针,并从该缓冲区指针直接初始化[UInt8]
数组。示例:
let floatArray: [Float] = [1.0, 2.0]
// Works also with a ContiguousArray:
// let floatArray: ContiguousArray<Float> = [1.0, 2.0]
let byteArray = floatArray.withUnsafeBytes Array($0)
print(byteArray) // [0, 0, 128, 63, 0, 0, 0, 64]
等效地(基于 Leo 的建议):
let byteArray = floatArray.withUnsafeBytes(Array.init)
字节数组包含以主机字节顺序表示的浮点数的二进制表示(在所有当前 Apple 平台上都是小端序)。可以转换为大端,但不能没有到整数数组的中间副本:
let floatArray: ContiguousArray<Float> = [1.0, 2.0]
let intArray = floatArray.map $0.bitPattern.bigEndian
let byteArray = intArray.withUnsafeBytes(Array.init)
print(byteArray) // 63, 128, 0, 0, 64, 0, 0, 0]
反向转换:一个简单的方法是
let floatArray2 = byteArray.withUnsafeBytes Array($0.bindMemory(to: Float.self))
print(floatArray2) // [1.0, 2.0]
但是,这要求字节数组的元素存储为浮点数正确对齐。如果不能保证,那么你可以这样做
var floatArray2 = [Float](repeating: 0.0, count: byteArray.count / MemoryLayout<Float>.stride)
_ = floatArray2.withUnsafeMutableBytes byteArray.copyBytes(to: $0)
print(floatArray2) // [1.0, 2.0]
【讨论】:
或withUnsafeBytes([UInt8].init)
@LeoDabus:好建议!甚至 withUnsafeBytes(Array.init)
也可以工作(使用自动类型推断)。
反方向会怎样?
非常感谢! Array($0)
或 Array.init
成功了。谢谢你们两位 MartinR @LeoDabus
@jiko meta.stackexchange.com/questions/5234/…以上是关于如何在 Swift 中将 Floats 的 ContiguousArray 转换为字节数组?的主要内容,如果未能解决你的问题,请参考以下文章