0

UInt8 値の配列を拡張したかったので、Swift 3でこのコードを書きました。

extension Array where Element: UInt8  {

}

しかし、私はこのエラーが発生しました:

タイプ 'Self.Generator.Element' は非プロトコル タイプ 'UInt8' に制限されています

では、どうすれば修正できますか?

4

1 に答える 1

3

この構文は、によって定義されElement: Xた型制約を課すことを意味します。ここで、は派生元のプロトコルまたはクラスでなければなりません。(値の型) element を持つ配列でのみ使用できる拡張機能を構築したい場合の回避策として、準拠するプロトコルのみを定義し、このプロトコルを拡張機能の型制約として使用できます。例えばElementXXElementArrayUInt8UInt8

protocol MyType {}
extension UInt8: MyType {}

extension Array where Element: MyType  {
    // ...
}

Element現在の実装では、拡張内のすべてのコードは、プロトコルで設計されているもの以外の型については何も知りませんMyType(つまり、現在は何も知りません)。拡張機能で達成したいことに応じて、 で利用可能な実装(たとえば、初期化子)MyTypeによって既に実現されていることがわかっている設計図を に追加できます。UInt8しかし、より賢明なアプローチは、が有用なプロトコルにUInt8準拠しているという事実を利用することです。プロトコル構成を使用することにより、これらのプロトコルによって設計されたすべてのメソッドは、拡張機能の :s ですぐに使用できますが、これらの要素は、独自のプロトコルに準拠する型(つまり、 のみ)に制限されます。UnsignedIntegerEquatableComparableElementMyTypeUInt8

protocol MyType {}
extension UInt8: MyType {}

extension Array where Element: MyType & UnsignedInteger {
    mutating func superfluouslyReplaceAllElements(with value: Element) {
        self = self.map { $0.advanced(by: $0.distance(to: value)) }
    } /* using 'advanced(by:)' and 'distance(to:)' methods of
         'Element', blueprinted in 'UnsignedInteger', to which 
         'Element' conforms */

    mutating func elementsSquaredWithOverflow() -> Bool {
        var overflow = false
        self = self.map {
            let result = Element.multiplyWithOverflow($0, $0)
            overflow = overflow || result.overflow
            return result.0
        }
        return overflow // did at least one element cause an arithmetic overflow?
    }
}

var foo: [UInt8] = [14, 87, 13, 240]
print(foo.elementsSquaredWithOverflow()) // true (at least one arithmetic overflow)
print(foo) // [196, 145, 169, 0]

foo.superfluouslyReplaceAllElements(with: 42)
print(foo) // 42, 42, 42, 42

var bar: [UInt16] = [14, 87, 13, 240]
bar.superfluouslyReplaceAllElements(with: 42)
    /* error: type 'UInt16' does not conform to protocol 'MyType' 
       OK, as expected!                                           */

ただし、これはプロトコルと型の制約に関する簡単な教訓にすぎません。バイトのコンテキストでシーケンスを操作する場合UInt8は、質問へのコメントで @vadian:s のアドバイスに従ってください。

于 2016-11-20T12:22:53.953 に答える