You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Swift中Identifiable结构体多属性生成UInt类型id编译失败的解决方法

问题修复方案

你的代码编译失败主要有三个核心问题,逐个解决就能正常运行:

1. 语法错误:括号不匹配

原代码里的括号嵌套混乱,多了一个右括号,最后一行也没闭合所有括号。比如第二行的((i3 << 45) + (i4 << 40)))多了一个),最后一行的((i11 << 5) + i12缺少闭合的)))。

2. 类型不匹配:UInt64转UInt32

Swift里UInt默认是64位(在64位平台),位移后的结果是UInt64类型,但你要返回UInt32,必须显式转换,否则编译器会报错。

3. 逻辑缺陷:位数溢出导致ID冲突

UInt32只有32位,但你现在给12个属性每个分配5位(12*5=60位),远超过32位的容量,最终转换时会截断高位,大概率会出现不同对象生成相同ID的情况,完全达不到唯一标识的目的。


修复后的代码方案(推荐用哈希生成,更可靠)

如果只是为了生成能用于对象比较的唯一ID,没必要手动位移组合,Swift的Hasher可以高效组合多个属性生成哈希值,既简洁又能避免位数溢出问题:

struct OBJ: Identifiable {
    var i1: UInt
    var i2: UInt
    var i3: UInt
    var i4: UInt
    var i5: UInt
    var i6: UInt
    var i7: UInt
    var i8: UInt
    var i9: UInt
    var i10: UInt
    var i11: UInt
    var i12: UInt

    var id: UInt32 {
        var hasher = Hasher()
        hasher.combine(i1)
        hasher.combine(i2)
        hasher.combine(i3)
        hasher.combine(i4)
        hasher.combine(i5)
        hasher.combine(i6)
        hasher.combine(i7)
        hasher.combine(i8)
        hasher.combine(i9)
        hasher.combine(i10)
        hasher.combine(i11)
        hasher.combine(i12)
        return UInt32(hasher.finalize())
    }
}

如果你坚持手动位移(需调整位数)

如果一定要用位移的方式,必须把总位数控制在32位以内,比如给每个属性分配2位(12*2=24位,剩下8位留空),同时修正语法和类型转换:

struct OBJ: Identifiable {
    var i1: UInt
    var i2: UInt
    var i3: UInt
    var i4: UInt
    var i5: UInt
    var i6: UInt
    var i7: UInt
    var i8: UInt
    var i9: UInt
    var i10: UInt
    var i11: UInt
    var i12: UInt

    var id: UInt32 {
        // 先把每个属性截断到2位,再位移组合
        let part1 = (i1 & 0b11) << 22
        let part2 = (i2 & 0b11) << 20
        let part3 = (i3 & 0b11) << 18
        let part4 = (i4 & 0b11) << 16
        let part5 = (i5 & 0b11) << 14
        let part6 = (i6 & 0b11) << 12
        let part7 = (i7 & 0b11) << 10
        let part8 = (i8 & 0b11) << 8
        let part9 = (i9 & 0b11) << 6
        let part10 = (i10 & 0b11) << 4
        let part11 = (i11 & 0b11) << 2
        let part12 = i12 & 0b11
        
        return UInt32(part1 | part2 | part3 | part4 | part5 | part6 | part7 | part8 | part9 | part10 | part11 | part12)
    }
}

注意:手动位移的方式很容易因为属性值超过分配的位数导致ID冲突,所以更推荐用Hasher的方案。

内容的提问来源于stack exchange,提问作者Pusik Park

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.19 01:27:50