Фатальная ошибка преобразования кода Java в Swift: Недостаточно битов для представления переданного значения

#java #android #ios #swift #bit-manipulation

Вопрос:

Я пытаюсь создать приложение iOS на основе существующего приложения для Android и должен преобразовать функцию, связанную с переключением битов с Java на Swift. Это исходная функция в Java:

 public static void BUF_U32_BE(byte[] d, int loc, int val) {
    d[loc] = (byte)(val >> 24);
    d[loc 1] = (byte)(val >> 16);
    d[loc 2] = (byte)(val >> 8);
    d[loc 3] = (byte)(val amp; 0xFF);
}
 

Это была моя попытка преобразовать функцию в Swift:

 func BUF_U32_BE(byteArray: [UInt8], loc:  Int, val: Int)  -> [UInt8]{
    var d = byteArray;
    d[loc] = UInt8((val >> 24));
    d[loc 1] = UInt8((val >> 16));
    d[loc 2] = UInt8((val >> 8));
    d[loc 3] = UInt8((val amp; 0xFF));
    return d;
}
 

При запуске версии Swift я получаю ошибку:

Неустранимая ошибка: Недостаточно битов для представления переданного значения

Это строка, которая приводит к ошибке:

 d[loc 1] = UInt8((val >> 16));
 

Что может быть причиной этой проблемы и что я должен сделать, чтобы исправить ее?

Комментарии:

1. Я понятия не имею о swift, но UInt8((val >> 16) amp; 0xFF); работает ли это?

Ответ №1:

Ты ищешь UInt8.init(truncatingIfNeeded:) .


Кроме того, этот byteArray: [UInt8] параметр довольно шаткий. Он передается, копируется, мутирует и возвращается. С него никогда не читали. Это довольно странно. Я думаю, вы ожидаете, что это попадет прямо byteArray в loc индекс, но так как вы делаете копию, на самом деле этого не происходит.

В Swift мы бы просто возвращали кортеж для фиксированного числа значений, подобных этому:

 // FIXME: `BUF_U32_BE` is a bad name. Perhaps `splitIntoBytes(_:)`?
func BUF_U32_BE(val: Int) -> (UInt8, UInt8, UInt8, UInt8) {
    return (
        UInt8(truncatingIfNeeded: val >> 24),
        UInt8(truncatingIfNeeded: val >> 16),
        UInt8(truncatingIfNeeded: val >>  8),
        UInt8(truncatingIfNeeded: val >>  0),
    )
}