代码之家  ›  专栏  ›  技术社区  ›  Pablo

什么是“元素”类型?

  •  9
  • Pablo  · 技术社区  · 7 年前

    阅读 Swift编程语言 书我看过很多关于类型的参考文献 Element ,用于定义集合项的类型。然而,我找不到关于它的任何文档,它是类还是协议?它有什么样的功能/方法/属性?

    struct Stack<Element>: Container {
        // original Stack<Element> implementation
        var items = [Element]()
        mutating func push(_ item: Element) {
            items.append(item)
        }
        ...
    
    4 回复  |  直到 7 年前
        1
  •  5
  •   Ahmad F    7 年前

    如果我们试着追查 Element 在处理集合时,我们会注意到它与 Iterator 协议让我们更清楚地说明:

    Swift Collection types ( Array ,则, Dictionary Set )都符合 Collection protocol 因此,当谈到收集协议时,我们可以看到它的根是 Sequence protocol :

    提供顺序、, 迭代 访问其元素。

    序列具有 要素 迭代器 关联类型,声明为:

    associatedtype Element
    
    associatedtype Iterator : IteratorProtocol where Iterator.Element == Element
    

    你可以在序列上查看它 source code

    如图所示, Iterator 还有一个 Element associated type ,这与序列元素相比,这意味着什么?

    IteratorProtocol 是执行实际工作的人员:

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

    因此,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() 方法只能用于 我的协议 类型( MyStruct 在我们的例子中)将字符串分配给 MyElement公司 ,表示如果 MyStruct公司 已实施为:

    struct MyStruct: MyProtocol {
        typealias MyElement = Int
    }
    

    你会的 能够:

    MyStruct().sayHello()
    

    您应该会看到编译时错误:

    '我的结构。MyElement(又名“Int”)不能转换为“String”

    Swift收款类型的逻辑相同:

    extension Array where Element == String {
        func sayHello() {
            print("Hello")
        }
    }
    
        2
  •  4
  •   Kamran    7 年前

    以下是 Apple 文档

    元素为稍后提供的类型定义占位符名称。 此未来类型可以在 结构定义。

        3
  •  3
  •   Gereon    7 年前

    Element 通常用作集合的泛型类型名称,如

    public struct Array<Element> { ... }
    

    因此,它是构建数组的基础,而不是语言预定义的内容。

        4
  •  2
  •   trndjc    4 年前

    Element 是专门为结构构建(和定义)的占位符。 与一些答案/意见不同, 要素 不能总是被替代 T 因为 T 没有适当的上下文是未定义的。例如,无法编译以下内容:

    infix operator ++
    
    extension Array {
        static func ++ (left: Array<T>, right: T) -> Array {
            ...
        }
    }
    

    编译器不知道什么 T 它只是一个任意的字母它可以是任何字母,甚至是符号( T 刚刚成为一种快速的惯例)。然而 编译:

    infix operator ++
    
    extension Array {
        static func ++ (left: Array<Element>, right: Element) -> Array {
            ...
        }
    }
    

    它可以编译,因为编译器知道 要素 是一个已定义的占位符,而不是任意组成的类型。