使用 Swift 的 withUnsafeMutableBytes 包装器时出现问题

Issue Using Swift's withUnsafeMutableBytes Wrapper

我正在尝试编写 Data 的扩展,允许我在各种转换中提取它。

我 运行 遇到了一个我不太明白的奇怪问题。

在我接触泛型之前,我正在尝试固定数据类型,并且我创建了这个方法:

func intValueFromData(_ inData: Data) -> Int64? {
    var number = Int64(0)
    let len = Swift.min(MemoryLayout<Int64>.size, inData.count)
    _ = withUnsafeMutableBytes(of: &number) {
        inData.copyBytes(to: [=11=], from: 0..<len)
    }

    return number
}

行得通。如果我这样做:

var int_64 = Int64(12345)

var data = Data(bytes: &int_64, count: MemoryLayout<Int64>.size)

let fetched = intValueFromData(data)

fetched 变为“12345”作为 Int64。

但是,当我尝试将相同的方法嵌入数据类型时,如下所示:

extension Data {
    mutating func intValueFromData() -> Int64? {
        var number = Int64(0)
        let len = Swift.min(MemoryLayout<Int64>.size, self.count)
        _ = withUnsafeMutableBytes(of: &number) {
            self.copyBytes(to: [=13=], from: 0..<len)
        }

        return number
    }
}

我收到一个编译时错误,提示“withUnsafeMutableBytes(of: &number)”不应有参数。

上次遇到这种情况,原来苹果明明屏蔽了一个功能,却忘了直截了当地告诉我们。

我不是这方面的专家,但我想知道是否有人可以阐明为什么 withUnsafeMutableBytes(of: &number) 在扩展中表现不同。

Data 的上下文中,withUnsafeMutableBytes 指的是 Data.withUnsafeMutableBytes(_:)

为了消除歧义并引用全局函数,明确地为模块名称添加前缀:_ = Swift.withUnsafeMutableBytes(of: &number) {

为了完成设置,这是我创建的通用函数:

/* ###################################################################################################################################### */
// MARK: - Data Extension -
/* ###################################################################################################################################### */
/**
 This extension adds the ability to extract data fron a Data instance, cast into various types.
 */
public extension Data {
    /* ################################################################## */
    /**
     This method allows a Data instance to be cast into various standard types.

     - parameter inValue: This is an inout parameter, and the type will be used to determine the cast.
     - returns: the cast value (the parameter will also be set to the cast value). Can be ignored.
     */
    @discardableResult
    mutating func castInto<T>(_ inValue: inout T) -> T {
        // Makes sure that we don't try to read past the end of the data.
        let len = Swift.min(MemoryLayout<T>.size, self.count)
        _ = Swift.withUnsafeMutableBytes(of: &inValue) {
            self.copyBytes(to: [=10=], from: 0..<len)
        }

        return inValue
    }
}