10

Swift 2.3 で次の拡張機能を作成しました。

extension CollectionType {
    /// Returns the element at the specified index iff it is within bounds, otherwise nil.
    subscript (safe index: Index) -> Generator.Element? {
        return indices.contains(index) ? self[index] : nil
    }
}

ただし、Swift 3.0 には機能がないことが判明しましたcontains()。代わりに、このメソッドの次の構文が提供されます。

indices.contains(where: { (<#Self.Indices.Iterator.Element#>) -> Bool in
    <# code ??? what should it do??? #>
})

問題は、ブロック内に何を含めるべきかわからないことです。それを移行するのに何か助けてください。

4

1 に答える 1

28

Swift 4 アップデート

Swift 4 では、関連付けられた type に節を持たせる機能のwhereおかげで、のtype がのと同じ型であることCollectionを強制するようになりました。IndicesElementCollectionIndex

したがって、これは次のように言えることを意味します。

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

SequenceSwift 3のプロトコルにcontains(_:)は、シーケンスが要素の場合にシーケンスの要素を受け入れるメソッドがまだありEquatableます。

extension Sequence where Iterator.Element : Equatable {
    // ...
    public func contains(_ element: Self.Iterator.Element) -> Bool
    // ...
}

発生している問題は、Collectionindicesプロパティ要件のタイプが変更されたためです。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の将来のバージョンで可能になる予定です)、型を に渡すことができることをコンパイラが認識する方法はありません。これは、タイプが必要な要素タイプに準拠して実装することが現在完全に可能であるためです。IndicesIterator.ElementIndexIndexcontains(_:)CollectionIndices

したがって、解決策は、拡張機能を単純に制約して、 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
    }
}
于 2016-10-30T17:48:39.127 に答える