单项目集合

温馨提示:本文最后更新于2024-08-13 10:19:03,某些文章具有时效性,若有错误或已失效,请在下方留言

代码内有什么?

swift 标准库文件 Array.swift 中,可以检索到 insert() 方法,如下所示:

public mutating func insert(_ newElement: __owned Element, at i: Int) {
  _checkIndex(i)
  self.replaceSubrange(i..<i, with: CollectionOfOne(newElement))
}

内部的_checkIndex(i) 方法用来校验插入的位置是否有效,比如插入的位置是-1

但另一行代码更有趣:它用一个 CollectionOfOne 对象替换了一个子范围,其中包含了我们要插入的元素。这是一个非常有趣的类型,因为它听起来完全自相矛盾:集合将大量对象存储在一个地方,那么我们为什么要使用一个对象的集合呢?

创建单对象集合

因为 CollectionOfOne 也是一个集合,就像数组和集合一样,我们可以用同样的方法使用它。我们可以创建一个有起始值的集合:

var luckyNumbers = CollectionOfOne(13)

我们可以打印集合的 count

print(luckyNumbers.count) // 1

我们可以遍历集合中的项目

for luckyNumber in luckyNumbers {
    print(luckyNumber) // 13
}

我们可以通过他们的位置读取并改变值,位置始终为 0。

print(luckyNumbers[0]) // 13
luckyNumbers[0] = 7
print(luckyNumbers[0]) // 7

我们可以访问像 firstlast 这样的通用属性。

print(luckyNumbers.first == luckyNumbers.last) // true

…尽管在这种情况下,Swift 的规则意味着 firstlast 必须是可选的,尽管它们总是存在的。对于通常适用于可能为空的集合的任何属性和方法(例如读取随机值)来说,情况也是如此:

print(luckyNumbers.randomElement()!)

我们无法使用一系列方法来调整集合的大小,比如这些方法:

luckyNumbers.removeAll()
luckyNumbers.append(13)
luckyNumbers.insert(556, at: 0)

因此,这确实 一个完全由一个元素组成的集合,但为什么需要它–它有什么用处,Swift 本身为什么要使用它?

理解要点

CollectionOfOne 存在的原因有两个:一致性和性能。

一致性就是让代码符合某种形状。例如,我们可能有一个处理任何类型集合的函数,就像这样。

func printItems(in collection: any Collection) {
    for item in collection {
        print(item)
    }
}

我们已经可以传递一个数组或者集合,但是我们不能传递一个单独的项目。如果没有 CollectionOfOne,我们就不能这样做,因为 CollectionOfOne 就是一个集合,所以这种代码是完全有效的:

printItems(in: luckyNumbers)

这就引出了 CollectionOfOne 的第二个用途,即性能。与其传入一个单元素集合,我们完全可以这样写:

printItems(in: [7])

那我们为什么不这样做呢?至少在很多时候是这样的。然而,使用大小灵活的数组会产生超出所需的开销,因为我们知道我们总是只有一个项目。相反,使用 CollectionOfOne 只比直接传入整数稍慢一些,因为它只是对值进行了很薄的封装,就像 Optional 一样。

这种情况实际上比你想象的还要常见。例如,假设您有一个电影演员数组:

let cast = ["Stewart", "Frakes", "McFadden"]

然后多出一个人扮演角色:

let additional = "Sirtis"

如何将这两个数组组合起来创建一个新数组呢?有了 CollectionOfOne,答案很简单:

let finalCast = cast + CollectionOfOne(additional)

不仅如此,它的性能也很好,因为 “集合 “只是对值本身的一个薄如刀片的封装,其所有内部结构的实现都非常简单,以至于 Swift 会将它们内联以获得最快的速度。

所以,这就是 CollectionOfOne:你可能不经常用到它,但至少如果你在其他地方见过,你就会知道为什么会有它!

参考

  1. 文章来自: Hacking With Swift Plus
© 版权声明
THE END
喜欢就支持一下吧
点赞10 分享
评论 抢沙发

请登录后发表评论

    暂无评论内容