gpt4 book ai didi

swift - Swift 中 'type punning' 的优雅方式是什么?

转载 作者:行者123 更新时间:2023-12-03 23:47:32 26 4
gpt4 key购买 nike

用 Swift 编写,我有一个特定的需求,可能是类型双关的候选者。我正在从磁盘镜像中读取文件,它们存在于连续的 512 字节扇区中。文件以 Data 的形式从磁盘中脱离出来struct 很容易转换为字节数组和/或 512 字节 DataSlices无需复制。

到现在为止还挺好!一个文件可以快速表示为包含 512 UInt8 的数组集合。单位。但是,某些磁盘扇区(通常包含元数据)最好将其视为 256 UInt16项目。理想情况下,我希望能够以任何一种方式引用内存中的扇区,而无需进行任何复制。

现在,我正在采取一种简单的方法,将一个扇区(需要两个副本)复制到类似以下内容中:

struct Sector {
let bytes: [UInt8]
let words: [UInt16]
. . .

init() {
self.bytes = Array(repeating: 0, count: 512)
self.words = Array(repeating: 0, count: 256)
. . .

然后引用 sector.wordssector.bytes取决于哪个合适。幸运的是, [UInt16]扇区比它们的字节等价物少得多,所以这并不太糟糕;并且任何给定的扇区都是一个或另一个,我不必担心更改 bytes不变 words (虽然这是等待发生的事故)。

我读到的所有内容都谴责双关语 [UInt8][UInt16]数组和 Swift 的“不安全”内存函数有点吓人。我正在想办法让 .words在上面的结构体中占用与 .bytes相同的内存并希望得到一些建议。

我仍在研究这个..如果我发现有值(value)的东西,我会分享。

最佳答案

您正在寻找 https://stackoverflow.com/a/38024025/341994 中描述的技术.将数据保存在 Data 中,并根据需要将其作为 UInt8 或 UInt16 数组访问。 (实际上 Data 是一个 UInt8 数组,所以当你想把它看作一个 UInt16 数组时,你真的只需要做一些特殊的事情。)示例:

extension Data {
init<T>(fromArray values: [T]) {
self = values.withUnsafeBytes { Data($0) }
}
func toArray<T>(type: T.Type) -> [T] where T: ExpressibleByIntegerLiteral {
var array = Array<T>(repeating: 0, count: self.count/MemoryLayout<T>.stride)
_ = array.withUnsafeMutableBytes { copyBytes(to: $0) }
return array
}
}

let eights : [UInt8] = [1,2,3,4]
let data = Data(fromArray:eights)
let sixteens = data.toArray(type: UInt16.self)
print(sixteens) // 513, 1027

这是正确的答案,假设正确的字节序;
  • 0b00000001是 1
  • 0b00000010是 2

  • 所以,假设低字节高字节:
  • 0b0000001000000001是 513
  • 关于swift - Swift 中 'type punning' 的优雅方式是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61721165/

    26 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com