Swift 中 Java 字节数组的正确等价物是什么?

What is the right equivalent for Java array of bytes in Swift?

我才刚刚开始 Swift 开发。我在 Java 中有以下方法:

  public static byte[] addChecksum(byte[]command, boolean isDeviceSendFormat) {
    int checksum = 0;
    int l = command.length;
    for (int i=0; i<l-2; i++) {

        if (i==1 && isDeviceSendFormat==true) {
            continue;
        }

        int val = command[i];
        if (val < 0) {
            val = 0x100 + val;
        }
        checksum += val;
    }

    if (l > 2) {
        if (isDeviceSendFormat == false) {
            command[l - 1] = (byte) (checksum % 0x100);  // LSB
            command[l - 2] = (byte) (checksum / 0x100);  // MSB
        }
        else {
            command[l - 2] = (byte) (checksum % 0x100);  // LSB
            command[l - 1] = (byte) (checksum / 0x100);  // MSB
        }
    }

    return command;
}

我需要翻译成 Swift 但我遇到了一些问题,这是我目前得到的:

func addCheckSum(bufferInput:[UInt8], isDeviceSendFormat: Bool) -> [UInt8]{
    var checksum: UInt8 = 0
    var length: Int = 0
    var iIndex: Int
    var bufferOutput: [UInt8]

    length = bufferInput.count        

    for (index, value) in bufferInput.enumerated() {
        if index < bufferInput.count - 2 {
            if value == 1 && isDeviceSendFormat {
                continue
            }

            var val:UInt8 = bufferInput[index]
            if (val < 0) {
                val = 0x100 + val //Error line
            }
            checksum = checksum + val
        }
    }
}

但我收到以下错误:Integer literal '256' overflows when stored into 'UInt8' 在上面代码的注释行。如何将此方法从 Java 转换为 Swift?

这是我将您的 Java 代码翻译成 Swift:

public static func addChecksum(_ command: inout [UInt8], isDeviceSendFormat: Bool) -> [UInt8] {
    var checksum: UInt32 = 0
    let l: Int = command.count
    for i in 0..<l-2 {

        if i == 1 && isDeviceSendFormat {
            continue
        }

        let val = UInt32(command[i])
        //No need to modify `val` as it takes non-negative value when `command` is `[UInt8]`.
        checksum += val
    }

    if l > 2 {
        if !isDeviceSendFormat {
            command[l - 1] = UInt8(checksum % 0x100)  // LSB
            command[l - 2] = UInt8(truncatingIfNeeded: checksum / 0x100)  // Next to LSB
        } else {
            command[l - 2] = UInt8(checksum % 0x100)  // LSB
            command[l - 1] = UInt8(truncatingIfNeeded: checksum / 0x100)  // Next to LSB
        }
    }

    return command
}

//Assuming `command` is not too long as to make integer overflow in `checksum += val`.

一些注意事项:

  • 您的 Java 代码的这 3 行:

    if (val < 0) {
        val = 0x100 + val;
    }
    

    val 为负时,通过添加 0x100(=256) 将值 -128...127 转换为 0...255。所以,val 取 0...255 之间的任何值,所以,我选择 [UInt8] 代替 command。当您选择 UInt8 时,Java 中的上面 3 行在 Swift 中不需要。

  • 在您的 Swift 代码中,您为 checksumval 选择了 UInt8,但在 [=51] 中选择了 int =] 是 32 位长,我为他们选择 UInt32。假设整数溢出永远不会发生,它们只取 non-negative 个值,所以 non-negative 32 位长整数是合适的。


Swift 中没有 Java 的 byte[] 的直接等价物。所以,在某些情况下 [UInt8][Int8] 更合适。而且你可以发现很多情况下Java的byte[]被翻译成了Swift的Data