阅读 Swift编程语言一书我已经看到了Element
类型的引用数,用于定义集合项的类型。但是,我找不到任何关于它的文档,是类,协议吗?它有什么样的功能/方法/属性?
struct Stack<Element>: Container {
// original Stack<Element> implementation
var items = [Element]()
mutating func push(_ item: Element) {
items.append(item)
}
...
答案 0 :(得分:3)
以下是Apple文档
中的定义元素为稍后提供的类型定义占位符名称。 这种未来类型可以在其中的任何地方称为元素 结构的定义。
答案 1 :(得分:1)
Element
通常用作集合的通用类型名称,如
public struct Array<Element> { ... }
所以这是你构建你的数组,而不是语言预定义的东西。
答案 2 :(得分:1)
如果我们尝试跟踪在使用集合时我们如何获得Element
的想法,我们会注意到它与 Iterator 协议有关。让我们说清楚:
Swift Collection types(Array,Dictionary和Set)都符合Collection protocol。因此,当涉及到Collection协议时,我们可以看到它的根是Sequence protocol:
提供对其元素的顺序,迭代访问的类型。
序列有一个元素和迭代器相关类型,声明为:
associatedtype Element
associatedtype Iterator : IteratorProtocol where Iterator.Element == Element
您可以在序列{{3}}上查看它。
如图所示,Iterator
也有source code,与序列元素进行比较,这意味着什么?
Element associated type是完成实际工作的人:
IteratorProtocol协议与Sequence紧密相关 协议。序列通过创建提供对元素的访问 迭代器,它跟踪其迭代过程并返回一个 元素,因为它在序列中前进。
因此,Element将是序列返回元素的类型。
<强>编码强>
为了使其易于理解,您可以实现这样的代码来模拟案例:
protocol MyProtocol {
associatedtype MyElement
}
extension MyProtocol where MyElement == String {
func sayHello() {
print("Hello")
}
}
struct MyStruct: MyProtocol {
typealias MyElement = String
}
MyStruct().sayHello()
注意 - 如上所示 - 实现MyProtocol
的扩展使得MyElement
关联类型对于where子句是明智的。
因此,sayHello()
方法仅适用于MyProtocol
类型(在我们的例子中为MyStruct
),它将字符串分配给MyElement
,表示如果MyStruct
具有已实施为:
struct MyStruct: MyProtocol {
typealias MyElement = Int
}
你将 能够:
MyStruct().sayHello()
您应该看到编译时错误:
&#39; MyStruct.MyElement&#39; (又名&#39; Int&#39;)不能转换为&#39; String&#39;
Swift集合类型的逻辑相同:
extension Array where Element == String {
func sayHello() {
print("Hello")
}
}
答案 3 :(得分:1)
Element
是用于结构的专用(且已定义)占位符。 与某些答案/建议不同,Element
不能总是代替T
,因为T
没有适当的上下文是不确定的。例如,以下内容将无法编译:
infix operator ++
extension Array {
static func ++ (left: Array<T>, right: T) -> Array {
...
}
}
编译器不知道T
是什么,它只是一个任意字母-可以是任何字母甚至符号(T
刚刚成为Swift约定)。但是,此将进行编译:
infix operator ++
extension Array {
static func ++ (left: Array<Element>, right: Element) -> Array {
...
}
}
之所以进行编译,是因为编译器知道Element
是什么,它是定义的占位符,而不是任意组成的类型。