1

(必要に応じて質問のタイトルを自由に変更してください)

私は多くの BLE データを扱っており、デバッグの目的でUInt8HEX計算された変数で簡単に拡張できることがわかりました。

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次に、これを利用してandhexメソッドのデフォルトの実装を提供したい部分です。

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プロトコルとして、そのような文字列初期化子で使用できる型 ( ) を採用する型になることを保証できないと言っています。whereそれで初めて節を使えると思った。プロトコル拡張を次のように変更しました。

extension HexPrintable where Self == CVarArgType { ...

これはにつながりSame-type requirement makes generic parameter 'Self' non-genericます。その時点で私のアマチュアタイプの理論家の理解があふれました。異なる UInt サイズで 2 つの拡張メソッドを機能させる魔法は何ですか?

4

1 に答える 1

1

正しい構文は次のようになります。

extension HexPrintable where Self : CVarArgType { ... }

または、HexPrintableプロトコルを次から継承させCVarArgTypeます。

protocol HexPrintable : CVarArgType {
    var hexDigitCount:Int { get }
}

出力幅を決定するためIntegerTypeに を使用して、単一の拡張機能を使用して同じ機能を実装できることに注意してください。sizeofValue()

extension IntegerType where Self : CVarArgType {
    var HEX : String {
        let size = sizeofValue(self)
        return String(format: "%0\(2*size)X", self)
    }
}

しかし、別の問題があります: %Xformat はInt32引数を必要とします (Cint型に対応)。あなたと私の上記のコードは、32 ビット整数の範囲を超える値に対して正しい結果を生成しません。

その問題に対するさまざまな可能な解決策は、たとえば、 すべての整数型に対して一般的な整数から 16 進数への関数を作成するには? (そして、もう1つ追加しました)。

于 2015-10-22T19:08:36.520 に答える