UInt8 値の配列を拡張したかったので、Swift 3でこのコードを書きました。
extension Array where Element: UInt8 {
}
しかし、私はこのエラーが発生しました:
タイプ 'Self.Generator.Element' は非プロトコル タイプ 'UInt8' に制限されています
では、どうすれば修正できますか?
UInt8 値の配列を拡張したかったので、Swift 3でこのコードを書きました。
extension Array where Element: UInt8 {
}
しかし、私はこのエラーが発生しました:
タイプ 'Self.Generator.Element' は非プロトコル タイプ 'UInt8' に制限されています
では、どうすれば修正できますか?
この構文は、によって定義されElement: X
た型制約を課すことを意味します。ここで、は派生元のプロトコルまたはクラスでなければなりません。(値の型) element を持つ配列でのみ使用できる拡張機能を構築したい場合の回避策として、準拠するプロトコルのみを定義し、このプロトコルを拡張機能の型制約として使用できます。例えばElement
X
X
Element
Array
UInt8
UInt8
protocol MyType {}
extension UInt8: MyType {}
extension Array where Element: MyType {
// ...
}
Element
現在の実装では、拡張内のすべてのコードは、プロトコルで設計されているもの以外の型については何も知りませんMyType
(つまり、現在は何も知りません)。拡張機能で達成したいことに応じて、 で利用可能な実装(たとえば、初期化子)MyType
によって既に実現されていることがわかっている設計図を に追加できます。UInt8
しかし、より賢明なアプローチは、が有用なプロトコルにUInt8
準拠しているという事実を利用することです。プロトコル構成を使用することにより、これらのプロトコルによって設計されたすべてのメソッドは、拡張機能の :s ですぐに使用できますが、これらの要素は、独自のプロトコルに準拠する型(つまり、 のみ)に制限されます。UnsignedInteger
Equatable
Comparable
Element
MyType
UInt8
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 のアドバイスに従ってください。