首页 > 解决方案 > Java 到 Swift 代码转换致命错误:没有足够的位来表示传递的值

问题描述

我正在尝试基于现有的 Android 应用程序构建一个 iOS 应用程序,并且必须将一个涉及从 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 & 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 & 0xFF));
    return d;
}

运行 Swift 版本时,我收到错误消息:

致命错误:没有足够的位来表示传递的值

这是产生错误的行:

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

什么可能导致这个问题,我应该怎么做才能解决它?

标签: javaandroidiosswiftbit-manipulation

解决方案


你正在寻找UInt8.init(truncatingIfNeeded:).


顺便说一句,这个byteArray: [UInt8]参数非常不稳定。它被传入、复制、变异和返回。它从来没有读过。这很奇怪。我认为您希望这会直接出现byteArrayloc索引中,但是由于您正在制作副本,因此实际上并没有发生。

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

推荐阅读