Swift 使用 CollectionType 的协议和协议扩展

Swift Protocols and Protocols Extensions With CollectionType

我不理解 swift 中 array.indexOf() 的 return 类型。 当我命令单击该函数时,它会将我带到协议扩展:

extension CollectionType where Generator.Element : Equatable {

/// Returns the first index where `value` appears in `self` or `nil` if
/// `value` is not found.
///
/// - Complexity: O(`self.count`).
func indexOf(element: Self.Generator.Element) -> Self.Index?
}

方法indexOf returns Self.Index?,

它怎么知道它是一个 Int?

如果您查看 Swift header 的 _CollectionDefaultsType,您将看到协议定义如下,

protocol _CollectionDefaultsType : SequenceType {

    /// A type that represents a valid position in the collection.
    ///
    /// Valid indices consist of the position of every element and a
    /// "past the end" position that's not valid for use as a subscript.
    typealias Index : ForwardIndexType

    /// The position of the first element in a non-empty collection.
    ///
    /// In an empty collection, `startIndex == endIndex`.
    var startIndex: Self.Index { get }

    /// The collection's "past the end" position.
    ///
    /// `endIndex` is not a valid argument to `subscript`, and is always
    /// reachable from `startIndex` by zero or more applications of
    /// `successor()`.
    var endIndex: Self.Index { get }

    /// Returns the first element of `self`, or `nil` if `self` is empty.
    var first: Self.Generator.Element? { get }
}

如果翻遍Swiftheader文件,可以看到Array的定义如下

struct Array<T> : CollectionType, SequenceType, _CollectionDefaultsType, _CollectionGeneratorDefaultsType, MutableCollectionType, Sliceable, _Sliceable, _DestructorSafeContainer {

    /// The type of element stored by this `Array`.
    typealias Element = T

    /// Always zero, which is the index of the first element when non-empty.
    var startIndex: Int { get }

    /// A "past-the-end" element index; the successor of the last valid
    /// subscript argument.
    var endIndex: Int { get }
    subscript (index: Int) -> T

    /// Return a *generator* over the elements.
    ///
    /// - Complexity: O(1).
    func generate() -> IndexingGenerator<[T]>

    /// A type that can represent a sub-range of an `Array`.
    typealias SubSlice = ArraySlice<T>
    subscript (subRange: Range<Int>) -> ArraySlice<T>
}

getterstartIndex,endIndex,first是从协议_CollectionDefaultsType实现的,其类型是Self.Index 。现在,如果您查看 indexOf 方法的定义,它是作为协议扩展实现的,类型为 Self.Index

extension CollectionType where Generator.Element : Equatable {

    /// Returns the first index where `value` appears in `self` or `nil` if
    /// `value` is not found.
    ///
    /// - Complexity: O(`self.count`).
    func indexOf(element: Self.Generator.Element) -> Self.Index?
}

因此,类型 Index 从上述两个实现中推断为 Int。

顺便说一下,如果你在 playground 中输入 Array.Index 来查看 Array 中的类型 Index,自动完成显示类型为 Int,