Swift 4 アップデート
Swift 4 では、関連付けられた type に節を持たせる機能のwhere
おかげで、のtype がのと同じ型であることCollection
を強制するようになりました。Indices
Element
Collection
Index
したがって、これは次のように言えることを意味します。
extension Collection {
/// Returns the element at the specified index iff it is within bounds, otherwise nil.
subscript (safe index: Index) -> Element? {
return indices.contains(index) ? self[index] : nil
}
}
スイフト3
Sequence
Swift 3のプロトコルにcontains(_:)
は、シーケンスが要素の場合にシーケンスの要素を受け入れるメソッドがまだありEquatable
ます。
extension Sequence where Iterator.Element : Equatable {
// ...
public func contains(_ element: Self.Iterator.Element) -> Bool
// ...
}
発生している問題は、Collection
のindices
プロパティ要件のタイプが変更されたためです。Swift 2 ではタイプでしたがRange<Self.Index>
、Swift 3 ではタイプIndices
(Collection
プロトコルの関連付けられたタイプ) です。
/// A type that can represent the indices that are valid for subscripting the
/// collection, in ascending order.
associatedtype Indices : IndexableBase, Sequence = DefaultIndices<Self>
現在 Swift では、 が型であることをプロトコル自体で表現する方法がないため(ただしCollection
、これはSwiftの将来のバージョンで可能になる予定です)、型を に渡すことができることをコンパイラが認識する方法はありません。これは、タイプが必要な要素タイプに準拠して実装することが現在完全に可能であるためです。Indices
Iterator.Element
Index
Index
contains(_:)
Collection
Indices
したがって、解決策は、拡張機能を単純に制約して、 type の要素が確実にIndices
含まIndex
れるようにし、 に渡すことができるようにすることindex
ですcontains(_:)
。
extension Collection where Indices.Iterator.Element == Index {
/// Returns the element at the specified index iff it is within bounds, otherwise nil.
subscript (safe index: Index) -> Iterator.Element? {
return indices.contains(index) ? self[index] : nil
}
}