You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Swift中Stack遵循ExpressibleByArrayLiteral的init写法为何与Apple文档不同?

为什么Stack的ExpressibleByArrayLiteral实现和Apple文档示例不同?

别担心,这两种写法都是完全合规的,只是各自适配了结构体的内部逻辑而已!咱们一步步拆解清楚:

协议的核心要求

ExpressibleByArrayLiteral协议只有一个硬性规定:你必须实现一个名为init(arrayLiteral:)的初始化方法,参数是可变参数类型Element...。不管是书中的Stack实现,还是Apple文档里的OrderedSet实现,都满足这个核心要求——这也是它们都能通过数组字面量初始化的原因。

两种实现的差异细节

书中Stack的简洁实现

先看你的Stack代码:

public struct Stack<Element> {
    private var storage: [Element] = []
    public init(_ elements: [Element]) {
        storage = elements
    }
}

extension Stack: ExpressibleByArrayLiteral {
    public init(arrayLiteral elements: Element...) {
        storage = elements
    }
}

这里的关键是:Stack的内部存储storage本身就是一个普通的[Element]数组,而协议要求的arrayLiteral参数(可变参数Element...)在方法内部会自动转换成[Element]类型。所以直接把elements赋值给storage是最直接高效的写法,完全不需要额外逻辑。

甚至你还可以复用Stack已有的初始化方法,把扩展里的代码改得更简洁:

public init(arrayLiteral elements: Element...) {
    self.init(elements)
}

效果和原代码完全一致,只是更复用了已有的逻辑。

Apple文档里OrderedSet的特殊实现

再看文档里的示例:

extension OrderedSet: ExpressibleByArrayLiteral {
    init(arrayLiteral: Element...) {
        self.init()
        for element in arrayLiteral {
            self.append(element)
        }
    }
}

这是因为OrderedSet是一个有序且不允许重复元素的集合,它的内部存储逻辑和普通数组不一样:直接把数组赋值进去会跳过它的去重、顺序维护逻辑。所以必须通过逐个调用append方法,让OrderedSet自己处理每个元素的添加过程(比如检查元素是否已存在、维护有序结构)。

总结一下

两种写法没有对错之分,只是根据结构体的内部实现逻辑选择了最适合的方式:

  • 如果你的结构体内部就是普通数组存储,直接赋值是最简洁高效的;
  • 如果你的结构体有特殊的元素处理规则(比如去重、自定义排序、状态校验),就需要逐个处理元素,调用自己的添加逻辑。

你能成功用var stack: Stack = [1.0, 2.0, 3.0, 4.0]初始化栈,就说明两种实现都是完全符合协议要求的~

内容的提问来源于stack exchange,提问作者Marcus Kim

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.08 16:07:56