#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),
)
}