Невозможно передать неизменяемое значение в качестве входного аргумента: вызов функции возвращает неизменяемое значение

Я разветвил этот проект, поэтому я не знаком со всеми деталями: https://github.com/nebs/hello-bluetooth/blob/master/HelloBluetooth/NSData%2BInt8.swift.

Все это является частью расширения NSData, которое я использую для отправки 8-битных значений в Arduino.

func int8Value() -> Int8 {
    var value: Int8 = 0
    copyBytes(to: &UInt8(value), count: MemoryLayout<Int8>.size)    //BUG

    return value
}

введите здесь описание изображения

Однако в Swift 3 появляется ошибка в разделе copyBytes. Хотя я видел некоторые решения, такие как передача адреса в параметре, я не хотел рисковать и ломать оставшиеся части кода. Любые предложения о том, что сделать для этого?


person ML.    schedule 14.01.2017    source источник


Ответы (1)


Исходный код был неверным. UInt8(value) генерирует новое неизменное значение, в которое вы не можете записывать. Я предполагаю, что старый компилятор просто позволял вам сойти с рук, но это никогда не было правильным.

Что они хотели сделать, так это написать ожидаемый тип, а затем преобразовать тип в конце.

extension Data {
    func int8Value() -> Int8 {
        var value: UInt8 = 0
        copyBytes(to: &value, count: MemoryLayout<UInt8>.size)

        return Int8(value)
    }
}

Тем не менее, сегодня я бы так не поступил. Data автоматически приведет свои значения к любому типу, который вы хотите, поэтому этот способ безопаснее, проще и очень общий:

extension Data {
    func int8ValueOfFirstByte() -> Int8 {
        return withUnsafeBytes{ return $0.pointee }
    }
}

Или вот так, специфичный для целых чисел (и даже проще):

extension Data {
    func int8Value() -> Int8 {
        return Int8(bitPattern: self[0])
    }
}
person Rob Napier    schedule 14.01.2017
comment
Потрясающее объяснение! Большое спасибо! - person ML.; 14.01.2017
comment
Вы хотели использовать инициализатор init(bitPattern:) Int8 для первого и последнего примеров, верно? - person Hamish; 14.01.2017
comment
Я этого не делал, но ты прав. То, как я написал, рухнет. Спасибо. - person Rob Napier; 14.01.2017
comment
Я оригинальный автор кода, спасибо, что указали на ошибку и предложили решение! Я обновлю исходное репо, чтобы отразить это. - person nebs; 20.02.2017