まず、内部の種類とプロトコルの操作には注意が必要です。プロトコル名(_ArrayProtocol
)の前に付いているアンダースコアはちょうどこれを示しています。 Swiftを使用している開発者が内部プロトコルの直接的/明示的な使用に頼ってはならないため、将来のSwift更新で警告なしに変更を促す可能性があることを意味します。 swift/stdlib/public/core/ArrayType.swiftから
internal protocol _ArrayProtocol: RangeReplaceableCollection, ...
。
今
、あなたのエラーについては、エラーメッセージがかなり
を言っていることはsubscript
て割り当てることができません:subscript
_ArrayProtocol
ために得る専用
、すなわち、subscript
には利用できていませんあなたの拡張機能の型自体として_ArrayProtocol
を使用しているので、デフォルトの実装を介して)それはsubscript
の青写真に対する設定を持っていますが、デフォルトの実装はありませんが、ゲッターのデフォルトの実装はRangeReplaceableCollection
から利用できます。
Element
(self
)をindex
に置き換えたい場合は、たとえば次のようにします。分のため、我々は内部プロトコルで直接作業の不適切の主題を残す場合は、我々が構築できる
replaceSubrange(index...index, with: [object])
:RangeReplaceableCollection
に自身が準拠プロトコルとして、_ArrayProtocol
に準拠するタイプに変異replaceSubRange(_:, with:)
method of RangeReplaceableCollection
アクセスを利用しますこのフィックスを実装する例です。実際に検証できる例です(あなたの質問であなたが提供したものとは対照的に...)。
enum Foo {
case created(Int)
case entered(Int)
case deleted(Int)
case left(Int)
case updated(Int)
}
// do not work directly with this _internal_ protocol!!
extension _ArrayProtocol where Iterator.Element == Int {
mutating func updateWithEvent(event: Foo) {
switch event {
case .created(let object):
append(object)
case .entered(let object):
append(object)
case .deleted(let object):
if let index = index(of: object) {
remove(at: index)
}
case .left(let object):
if let index = index(of: object) {
remove(at: index)
}
case .updated(let object):
if let index = index(of: object) {
replaceSubrange(index...index, with: [object])
}
}
}
}
ただし、このような拡張機能を内部プロトコルに実装しないでください。代わりに、公開タイプ/プロトコルへの拡張を実装することを検討してください。
enum Foo<T> {
case created(T)
case entered(T)
case deleted(T)
case left(T)
case updated(T)
}
extension Array where Element: Equatable {
mutating func updateWithEvent(event: Foo<Element>) {
switch event {
case .created(let object):
append(object)
case .entered(let object):
append(object)
case .deleted(let object):
if let index = index(of: object) {
remove(at: index)
}
case .left(let object):
if let index = index(of: object) {
remove(at: index)
}
case .updated(let object):
if let index = index(of: object) {
self[index] = object
}
}
}
}
注意ここに(あなた自身の延長、self
の使用量など)の内部_ArrayProtocol
の具体的な種類での作業とは対照的に、その、持っている:Equatable
に準拠Element
年代に拘束Array
の拡張機能として、 subscript
、Array
、もう1つはdoesのセッターがありません。これは、拡張子がArray
に適用されたときに、オリジナルの単純な要素置換self[index] = object
を適用できることを意味します。
ありがとうございました。完璧に動作しています! –
@スンウォクベクは喜んで援助します。 – dfri
_ArrayProtocolはSiwft 3.1では公開されなくなりましたが、同じタイプの要件を使用することができます(これは単純化しています):http://stackoverflow.com/questions/43338557/does-arraytype-or-arrayprotocol-not-available-イン・スウィフト3-1。 –