Cannot pass immutable value as inout argument: fun

2019-03-06 13:10发布

I forked this project, so I am not as familiar with all of the details: https://github.com/nebs/hello-bluetooth/blob/master/HelloBluetooth/NSData%2BInt8.swift.

This is all part of an extension of NSData that the I am using to send 8-bit values to an Arduino.

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

    return value
}

enter image description here

However, it appears in Swift 3 that this now throws an error in the copyBytes section. Although I have seen some solutions such as passing an address in the parameter, I did not want to risk breaking the remaining parts of the code. Any suggestions on what to do for this?

1条回答
Ridiculous、
2楼-- · 2019-03-06 13:28

The original code was incorrect. UInt8(value) generates a new, immutable value which you cannot write to. I assume the old compiler just let you get away with it, but it was never correct.

What they meant to do was to write to the expected type, and then convert the type at the end.

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

        return Int8(value)
    }
}

That said, I wouldn't do it that way today. Data will coerce its values to whatever type you want automatically, so this way is safer and simpler and very general:

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

Or this way, which is specific to ints (and even simpler):

extension Data {
    func int8Value() -> Int8 {
        return Int8(bitPattern: self[0])
    }
}
查看更多
登录 后发表回答