Двоичный оператор ' | 'не может быть применен к операндам типа 'Int' и 'UInt8'


Я хочу выполнить простую логику or на 2-битных картах, но Свифт считает, что это неправильно:

let u: UInt8 = 0b1
let i: Int = 0b10
i | u // Binary operator '|' cannot be applied to operands of type 'Int' and 'UInit8'

Как-нибудь приспособиться к выводу типа и все еще иметь эту работу?

Я всегда мог бы сделать i | Int(u) // 3, но это, я думаю, не оптимально.

1 2

1 ответ:

Один из фундаментальных принципов Swift заключается в том, что неявно преобразование между типами.

let u: UInt8 = 0b1
let i: Int = 0b10
i | Int(u)

Заставляет задуматься о необходимых преобразованиях и о том, какого типа должен быть результат., так что - это правильное решение (на мой взгляд).

Давайте рассмотрим другой пример:
let u: UInt8 = 128
let i: Int8 = -128

Что должно быть u|i? Оба

u | UInt8(i)
Int8(u) | i

Сбой во время выполнения, потому что u не находится в диапазоне Int8, а i не находится в диапазоне от UInt8. Оба

u | UInt8(bitPattern: i)   // result is `UInt8`
Int8(bitPattern: u) | i    // result is `Int8`

Будет работать, но как компилятор должен выбирать между ними? Можно конвертировать как некоторые более крупные виды, например

Int(u) | Int(i)

Но этот тип несколько произвольный, как он может автоматически выводиться из компилятора? А что такое " больший тип" ибо Int64 + UInt64 аргументы?

Вот почему я думаю, что явное преобразование является правильным решением.