Mic*_*ata 21 binary macos casting ios swift
我正在寻找一种直接的方法来将Int的位值转换为UInt,反之亦然.例如(为简单起见,使用8位整数)我想实现以下目的:
let unsigned: UInt8 = toUInt8(-1) // unsigned is 255 or 0xff
let signed: Int8 = toInt8(0xff) // signed is -1
Run Code Online (Sandbox Code Playgroud)
起初我提出了以下解决方案:
let unsigned = unsafeBitCast(Int8(-1), UInt8.self)
let signed = unsafeBitCast(UInt8(0xff), Int8.self)
Run Code Online (Sandbox Code Playgroud)
但Apple在"unsafeBitCast()"文档中声明如下:
..警告::打破Swift类型系统的保证; 小心使用.几乎总有一种更好的方法可以做任何事情.
有没有人有更好的方法?
rin*_*aro 38
你可以做:
let unsigned = UInt8(bitPattern: Int8(-1)) // -> 255
let signed = Int8(bitPattern: UInt8(0xff)) // -> -1
Run Code Online (Sandbox Code Playgroud)
存在许多类似的初始化器:
extension Int8 {
init(_ v: UInt8)
init(_ v: UInt16)
init(truncatingBitPattern: UInt16)
init(_ v: Int16)
init(truncatingBitPattern: Int16)
init(_ v: UInt32)
init(truncatingBitPattern: UInt32)
init(_ v: Int32)
init(truncatingBitPattern: Int32)
init(_ v: UInt64)
init(truncatingBitPattern: UInt64)
init(_ v: Int64)
init(truncatingBitPattern: Int64)
init(_ v: UInt)
init(truncatingBitPattern: UInt)
init(_ v: Int)
init(truncatingBitPattern: Int)
init(bitPattern: UInt8)
}
Run Code Online (Sandbox Code Playgroud)
我走的是代数路线。测试一直很痛苦,因为强类型很容易导致执行中断,PlayGround 从 toUInt 函数返回一个负值,它不断崩溃或在执行双重转换时出现有趣的错误(我打开了一个错误报告)。无论如何,这就是我最终的结果:
func toUint(signed: Int) -> UInt {
let unsigned = signed >= 0 ?
UInt(signed) :
UInt(signed - Int.min) + UInt(Int.max) + 1
return unsigned
}
func toInt(unsigned: UInt) -> Int {
let signed = (unsigned <= UInt(Int.max)) ?
Int(unsigned) :
Int(unsigned - UInt(Int.max) - 1) + Int.min
return signed
}
Run Code Online (Sandbox Code Playgroud)
我用所有极端值(UInt.min、UInt.max、Int.min、Int.max)对它们进行了测试,当 XCode 没有发疯时,它似乎可以工作,但看起来过于复杂。奇怪的是,可以使用 hashvalue 属性简单地实现 UInt 到 Int 位转换,如下所示:
signed = UInt.max.hashValue // signed is -1
Run Code Online (Sandbox Code Playgroud)
但显然它不能保证总是有效(它应该,但我宁愿不冒险)。
任何其他想法将不胜感激。
归档时间: |
|
查看次数: |
16085 次 |
最近记录: |