什么是“元素”类型?

Pab*_*blo 7 collections element swift

阅读Swift Programming Language一书我看到了许多对 type 的引用Element,它用于定义集合项的类型。但是,我找不到任何关于它的文档,它是类还是协议?它有什么样的功能/方法/属性?

struct Stack<Element>: Container {
    // original Stack<Element> implementation
    var items = [Element]()
    mutating func push(_ item: Element) {
        items.append(item)
    }
    ...
Run Code Online (Sandbox Code Playgroud)

Ahm*_*d F 5

Element如果我们尝试追踪在使用集合时如何获取的想法,我们会注意到它与迭代器协议有关。让我们说得更清楚:

Swift Collection 类型ArrayDictionarySet)都遵循Collection 协议。因此,说到Collection协议,我们可以看出它的根源是Sequence协议

一种提供对其元素的顺序、迭代访问的类型。

Sequence 有一个ElementIterator关联类型,声明为:

associatedtype Element

associatedtype Iterator : IteratorProtocol where Iterator.Element == Element
Run Code Online (Sandbox Code Playgroud)

您可以在 Sequence源代码中查看它。

如图所示,Iterator还有一个Element关联 type,它与序列 Element 进行比较,那么这意味着什么呢?

IteratorProtocol是执行实际工作的:

IteratorProtocol 协议与 Sequence 协议紧密相连。序列通过创建 迭代器来提供对其元素的访问,迭代器跟踪其迭代过程并 在序列中前进时一次返回一个元素。

因此,Element 将是返回到序列的元素的类型。


编码:

为了简单易懂,您可以实现这样的代码来模拟这种情况:

protocol MyProtocol {
    associatedtype MyElement
}

extension MyProtocol where MyElement == String {
    func sayHello() {
        print("Hello")
    }
}

struct MyStruct: MyProtocol {
    typealias MyElement = String
}

MyStruct().sayHello()
Run Code Online (Sandbox Code Playgroud)

请注意,如上所示,实现扩展以MyProtocol使MyElement关联类型对于 where 子句来说是合理的。

因此sayHello(),该方法仅适用于将 String 分配给 的MyProtocol类型(在我们的例子中) ,这意味着 if已实现为:MyStructMyElementMyStruct

struct MyStruct: MyProtocol {
    typealias MyElement = Int
}
Run Code Online (Sandbox Code Playgroud)

你将无法

MyStruct().sayHello()
Run Code Online (Sandbox Code Playgroud)

您应该看到编译时错误:

“MyStruct.MyElement”(又名“Int”)无法转换为“String”

对于 Swift 集合类型也是同样的逻辑:

extension Array where Element == String {
    func sayHello() {
        print("Hello")
    }
}
Run Code Online (Sandbox Code Playgroud)