【问题标题】:Convert Data to UInt32 using extension [duplicate]使用扩展名将数据转换为 UInt32 [重复]
【发布时间】:2019-04-22 10:39:29
【问题描述】:

我正在尝试为Data 类提供一个帮助方法来将字节转换为UInt32。到目前为止,这有效:

extension Data {    
    var uint32:UInt32 {
        return UInt32(littleEndian: self.withUnsafeBytes { (ptr: UnsafePointer<UInt32>) in ptr.pointee })
    }
}

从 swift 5 开始,编译器给出以下警告:

'withUnsafeBytes' is deprecated: use `withUnsafeBytes<R>(_: (UnsafeRawBufferPointer) throws -> R) rethrows -> R` instead`

经过一些研究,我尝试使用withUnsafeMutableBytesUnsafeMutablePointer&lt;UInt32&gt;

但这会产生错误:Cannot use mutating member on immutable value: 'self' is immutable。 (如果它不是不可变 getter 函数的一部分,这将起作用)

如何修复我的只读辅助变量,以便编译器不发出警告?

(当然同样适用于UInt8UInt16

【问题讨论】:

    标签: swift swift5


    【解决方案1】:

    试试这个:

    let data = Data([0x01,0x02,0x03,0x04])
    extension Data {
        var uint32:UInt32 {
            return UInt32(littleEndian: self.withUnsafeBytes { bytes in
                bytes.load(as: UInt32.self)
            })
        }
    }
    print(String(format: "%08X", data.uint32)) //->04030201
    

    新的withUnsafeBytes 传递了一个UnsafeRawBufferPointer,它有一个有用的方法load(as:)

    【讨论】:

    • 谢谢,@MartinR。我应该注意到它。坦率地说,我不知道我可以如此轻松地做出如此错位的Data
    • (之前的评论被不小心删除了。)这需要内存正确对齐,它会崩溃,例如为let data = Data([0x00, 0x01,0x02,0x03,0x04]).dropFirst()。 – Data 是它自己的切片类型,并且不能保证给定(或创建的)Data 完全对齐。也在这里讨论:forums.swift.org/t/about-data-alignment/17447
    【解决方案2】:

    您可以将self 分配给variable

    extension Data {
        var uint32:UInt32 {
            var data = self
            return UInt32(littleEndian: data.withUnsafeMutableBytes { (ptr: UnsafeMutablePointer<UInt32>) in ptr.pointee })
        }
    }
    

    【讨论】:

    • 它解决了与不变性相关的错误,但结果仍然有警告。似乎withUnsafeMutableBytes 也一样糟糕。
    猜你喜欢
    • 2016-09-06
    • 1970-01-01
    • 1970-01-01
    • 2022-01-22
    • 1970-01-01
    • 1970-01-01
    • 2019-07-18
    • 2011-07-17
    • 1970-01-01
    相关资源
    最近更新 更多