(не стесняйтесь переименовывать вопрос соответствующим образом)
Я работаю с большим количеством данных BLE, и в целях отладки мне было легко расширить UInt8
с помощью вычисляемой переменной HEX
:
extension UInt8 {
var HEX:String {
return String(format: "%02X", self)
}
}
// 190.HEX --> "BE"
Я обнаружил, что хочу строчный вариант. А потом захотелось и для UInt32
и UInt16
. Поскольку единственное, что меняется, — это количество цифр для печати, я подумал, что могу сделать это с помощью своего рода протокола (по крайней мере, в образовательных целях).
protocol HexPrintable {
var hexDigitCount:Int { get }
}
extension UInt8:HexPrintable {
var hexDigitCount:Int {
return 2
}
}
extension UInt16:HexPrintable {
var hexDigitCount:Int {
return 4
}
}
extension UInt32:HexPrintable {
var hexDigitCount:Int {
return 8
}
}
Затем следует часть, где я хочу воспользоваться этим и предоставить реализацию методов HEX
и hex
по умолчанию:
extension HexPrintable {
var HEX:String {
return String(format: "%0\(self.hexDigitCount)X", self)
}
var hex:String {
return String(format: "%0\(self.hexDigitCount)x", self)
}
}
Я получаю ошибку компилятора Argument type 'Self' does not conform to expected type 'CVarArgType'
.
Думаю, я понимаю это. В нем говорится, что в качестве протокола он не может гарантировать, что принятые типы будут иметь тип (CVarArgType
), который можно было бы использовать в инициализаторе String таким образом. Поэтому я подумал, что могу использовать предложение where
в первый раз. Я изменил расширение своего протокола, чтобы оно выглядело так:
extension HexPrintable where Self == CVarArgType { ...
Что приводит к Same-type requirement makes generic parameter 'Self' non-generic
. В этот момент мое теоретическое понимание шрифта-любителя переполнилось. Что за волшебство, чтобы заставить работать мои два метода расширения для разных размеров UInt?