编程初级iOS开发者

在Swift中存在哪些类型的集合,它们在内部实现上有何不同,以及何时使用哪种集合?

用 Hintsage AI 助手通过面试

答案。

在Swift中,有三种主要的标准集合:Array,Set和Dictionary。它们实现了不同的接口,内部结构各异,适用于不同的任务。

问题的历史:

在Swift中,集合的设计注重类型安全(type safety)和性能,包括值语义(value semantics)以及对于Arrays/Set/Dictionary的拷贝写入(Copy-on-Write)。

问题:

初学者开发者通常只使用Array,而在某些情况下更合适使用Set或Dictionary,这会导致内存的浪费并降低访问/查找速度。需要理解它们之间的不同之处。

解决方案:

Array

有序元素集合,通过索引访问,允许重复元素。通常通过动态缓冲区实现。

Set

无序的唯一元素集合(Hashable)。通过哈希值访问 — 非常快速,不允许重复。

Dictionary

键值对集合。键必须是Hashable。通过键访问值(通过哈希表)。

示例代码:

var arr: [Int] = [1, 2, 3, 4] var set: Set<Int> = [1, 2, 2, 3] var dict: [String: Int] = ["a": 1, "b": 2] // set == [1, 2, 3] — 重复项被丢弃

关键特性:

  • Array在索引访问时有效,支持顺序,但按值访问是线性的
  • Set在查找和检查元素存在时快速,仅存储唯一的Hashable值
  • Dictionary在按键查找(Hashable)时是最优的,不保持顺序,但快速查找和修改值

有陷阱的问题。

可以将非Hashable类型用作Set或Dictionary的元素吗?

不可以。要存储在Set/Dictionary中,元素必须是Hashable(具有唯一的哈希标识符)。否则,编译器不会允许创建集合。

struct Point {} // Set<Point> 将引发错误,因为Point不是Hashable

Set中元素的存储顺序与添加顺序相同吗?

不是。Set不保证顺序 — 迭代可以给出任何顺序。如果需要顺序,请使用Array。

尝试访问Dictionary中不存在的键会发生什么?

Dictionary将返回Optional。请注意 — 尝试通过不存在的键获取值将返回nil,而不是错误。

let val = dict["not exist"] // val — nil

常见错误和反模式

  • 使用Array查找唯一值(最好使用Set)
  • 使用Dictionary存储不需要通过键查找的值
  • 试图使用非Hashable类型作为键/值

生活中的例子

负面案例

开发者为用户的唯一列表使用Array,并通过contains查找唯一性。在大型列表中 — 需要大量时间进行检查。

优点:

  • 实现简单

缺点:

  • 线性复杂度查找,冗余存储重复项,对内存负担大

积极案例

同样的列表作为Set实现。检查存在性 — 立即,保证唯一值。

优点:

  • 快速访问,节省内存,排除重复项

缺点:

  • 不保证元素的顺序