如何在 Swift 中将浮点数的连续数组转换为字节数组?

jik*_*iko 3 arrays serialization binaryfiles swift

我正在尝试在 Swift 中将浮点的连续数组转换为字节数组,但在不使用 for 循环的情况下无法找到明智的方法。我一直在关注以前的帖子,例如How to conversion a double into a byte array in swift? ,但如果不逐一迭代获取每个元素,我无法检索数组的内容。

有没有一种优雅的方法可以直接将 ContigouslyArray 的字节“复制”到字节数组?

PS:我已经成功实现了将结构转换为字节数组,但无法对数组执行相同的操作。

Mar*_*n R 5

您可以使用该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]
Run Code Online (Sandbox Code Playgroud)

等效地(基于 Leo 的建议):

let byteArray = floatArray.withUnsafeBytes(Array.init)
Run Code Online (Sandbox Code Playgroud)

字节数组包含主机字节顺序的浮点数的二进制表示形式(在所有当前的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]
Run Code Online (Sandbox Code Playgroud)

反向转换:一个简单的方法是

let floatArray2 = byteArray.withUnsafeBytes { Array($0.bindMemory(to: Float.self)) }
print(floatArray2) // [1.0, 2.0]
Run Code Online (Sandbox Code Playgroud)

但是,这要求字节数组的元素存储针对浮点数正确对齐。如果不能保证那么你可以这样做

var floatArray2 = [Float](repeating: 0.0, count: byteArray.count / MemoryLayout<Float>.stride)
_ = floatArray2.withUnsafeMutableBytes { byteArray.copyBytes(to: $0) }
print(floatArray2) // [1.0, 2.0]
Run Code Online (Sandbox Code Playgroud)