I wish to perform simple or
logic on 2 bit maps, yet Swift thinks this is wrong:
let u: UInt8 = 0b1
let i: Int = 0b10
i | u // Binary operator '|' cannot be applied to operands of type 'Int' and 'UInit8'
Any way to conform to type inference and still have this working?
I could always do i | Int(u) // 3
but this, I think, is not optimal.
One of the fundamental principles of Swift is that is does not implicitly convert between types.
let u: UInt8 = 0b1
let i: Int = 0b10
i | Int(u)
forces you to think about the necessary conversions and what type the result should have, so that is the correct solution (in my opinion).
Let's consider another example:
let u: UInt8 = 128
let i: Int8 = -128
What should u|i
be? Both
u | UInt8(i)
Int8(u) | i
crash at runtime because u
is not in the range of an Int8
, and i
is not
in the range of an UInt8
. Both
u | UInt8(bitPattern: i) // result is `UInt8`
Int8(bitPattern: u) | i // result is `Int8`
would work, but how should the compiler choose between both? One could convert both to some larger type, for example
Int(u) | Int(i)
but that type is somewhat arbitrary, how could it automatically be inferred from the compiler? And what is the "larger type"
for Int64
+ UInt64
arguments?
That's why I think that an explicit conversion is the right solution.