Проблема с использованием Swift withUnsafeMutableBytes Wrapper - PullRequest
0 голосов
/ 21 апреля 2020

Я пытаюсь написать расширение для 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 ]

1 голос
/ 21 апреля 2020

В контексте Data, withUnsafeMutableBytes относится к Data.withUnsafeMutableBytes(_:).

Чтобы устранить неоднозначность и обратиться к глобальной функции, явно добавьте префикс имени модуля: _ = Swift.withUnsafeMutableBytes(of: &number) {

0 голосов
/ 21 апреля 2020

Просто чтобы завершить набор, вот созданная мной общая функция c:

/* ###################################################################################################################################### */
// 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
    }
}
...