gpt4 book ai didi

swift - 尝试用 Swift 模拟 C 联合会给出运行时异常

转载 作者:搜寻专家 更新时间:2023-11-01 07:26:25 25 4
gpt4 key购买 nike

在 C 中:

typedef unsigned char u8;
typedef unsigned short u16;

typedef union {
struct { u8 l,h; } b;
u16 w;
} Register;

在 Swift 中(使用带有关联值的枚举):

enum Register {
case b(UInt8, UInt8)
case w(UInt16)

var l: UInt8 {
switch(self) {
case .b(let l, _): return l
case .w(let w): return UInt8(w)
}
}

var h: UInt8 {
switch(self) {
case .b(_, let h): return h
case .w(let w): return UInt8(w >> 8)
}
}

var w: UInt16 {
switch(self) {
case .b(let l, let h): return UInt16(l | (h << 8))
case .w(let w): return w
}
}
}

这个有效:

let regA = Register.b(255, 0)
print(regA.l)
print(regA.h)
let regB = Register.w(UInt16(256))
print(regB.w)

而这并没有,导致运行时异常:

print(regA.w)
print(regB.l)
print(regB.h)

我无法找出问题所在,因为在枚举定义中跟踪问题似乎非常不可能。

最佳答案

我看到两个问题。

对于问题 1,您正在创建一个 UInt8来自UInt16如果您不限制该值,它将溢出。您可以使用 UInt8(truncatingBitPattern: w)UInt8(w & 0xff) .

对于问题 2,lh在声明中 UInt16(l | (h << 8))UInt8值,所以你溢出了UInt8你需要转换为 UInt16 移位和 or-ing 之前。

您的代码现在可以使用这 2 个修改:

enum Register {
case b(UInt8, UInt8)
case w(UInt16)

var l: UInt8 {
switch(self) {
case .b(let l, _): return l
case .w(let w): return UInt8(w & 0xff) // issue 1
}
}

var h: UInt8 {
switch(self) {
case .b(_, let h): return h
case .w(let w): return UInt8(w >> 8)
}
}

var w: UInt16 {
switch(self) {
case .b(let l, let h): return UInt16(l) | UInt16(h) << 8 // issue 2
case .w(let w): return w
}
}
}

关于swift - 尝试用 Swift 模拟 C 联合会给出运行时异常,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35813885/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com