Проблема с использованием Swift с оболочкой UnafeMutableBytes

Я пытаюсь написать расширение для 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: $0, from: 0..<len)
    }

    return number
}

Это работает. Если я сделаю это:

var int_64 = Int64(12345)

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

let fetched = intValueFromData(data)

извлеченный становится "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: $0, from: 0..<len)
        }

        return number
    }
}

Я получаю сообщение об ошибке времени компиляции: "withUnsafeMutableBytes(of: &number)"не должно быть аргументов.

В последний раз, когда я столкнулся с чем-то подобным, оказалось, что Apple явно заблокировала какую-либо функцию, но не сказала нам прямо.

Я не эксперт в таких вещах, но мне интересно, может ли кто-нибудь пролить свет на то, почему withUnsafeMutableBytes(of: &number) внутри расширения ведет себя иначе.

2 ответа

Решение

В контексте 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: $0, from: 0..<len)
        }

        return inValue
    }
}
Другие вопросы по тегам