swift - 数组值是否可选?

标签 swift

你能解释一下原因吗:

  • 当我使用 array.first 访问数组值时,它是可选的
  • 当我从索引值访问时不是吗?

示例:

var players = ["Alice", "Bob", "Cindy", "Dan"]
let firstPlayer = players.first
print(firstPlayer) // Optional("Alice")
let firstIndex = players[0]
print(firstIndex) // Alice

最佳答案

(这个问题的简短答案很好,正是你所需要的。我只是想更深入地了解为什么以及如何更普遍地与 Swift 集合以及底层类型交互。如果你只是想“如何我应该使用这些东西吗?”阅读接受的答案并忽略所有这些。)

数组遵循所有集合的规则。集合必须实现以下下标:

subscript(position: Self.Index) -> Self.Element { get }

所以要成为一个Collection,Array的下标必须接受它的Index并且无条件地返回一个Element。对于很多种类的Collections,不可能创建一个不存在的Index,但是Array使用Int作为它的Index,所以它必须处理你传递一个超出范围的Index的可能性。在那种情况下,返回一个Element是不可能的,它唯一的选择就是根本不返回。这通常采取使程序崩溃的形式,因为它通常比挂起程序更有用,后者是另一种选择。

(这隐藏了一点类型理论,即 Swift 中的每个函数在技术上都可以返回“崩溃”,但我们不会在类型系统中跟踪它。这样做是可能的,以区分函数可以崩溃和那些不能,但 Swift 不会。)

这自然会提出一个问题,即当您使用不存在的键下标时,为什么 Dictionary 不会崩溃。原因是 Dictionary 的 Index 不是它的 Key。它有一个很少使用的下标,它提供对 Collection 的一致性(在顶级代码中很少使用,但在 stdlib 内部非常常用):

subscript(position: Dictionary<Key, Value>.Index) -> Dictionary.Element { get }

Array 也可以做到这一点,拥有一个独立于 Int 的 Array.Index 类型,并使 Int 下标返回一个 Optional。在 Swift 1.0 中,我打开了一个雷达来请求它。该团队争辩说,这会使 Array 的常见使用变得过于困难,而且使用 Swift 的程序员已经习惯了将超出范围视为编程错误(崩溃)的想法。另一方面,字典通常使用不存在的键来访问,因此键下标应该是可选的。多年来使用 Swift 使我确信他们是对的。

一般来说你不应该下标数组除非你从数组中得到索引(即使用index(where:))。但是许多 Cocoa 模式使得下标变得非常自然(cellForRow(at:) 是最著名的)。尽管如此,在更纯粹的 Swift 代码中,使用任意 Int 进行下标通常表明存在设计问题。

相反,您应该经常使用 Collection 方法,例如 firstfirst(where:),它们返回 Optionals,通常更安全、更清晰,并使用 for 迭代它们-in 循环而不是下标。

关于swift - 数组值是否可选?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49384978/

相关文章:

ios - 在 UIPercentDrivenInteractiveTransition 中缓慢平移会导致故障

ios - 多项选择测验 : Need to set title of each button to each question multiple choice answer

ios - 如果以模态方式呈现另一个 View ,则保持 AVSpeechSynthesizer 播放

ios - 如何使用 REST API 从 Parse.com 下载文件?

testing - Swift 中的功能测试。模拟应用程序流程

swift - 无法将用户 ID 指定为引用

iOS Swift 将 GPS 坐标存储到数组中

arrays - 在 Swift 3 中从 JSON 解析数组文字

ios - OpentTok (iOS) 如何订阅 hasAudio 流变化

ios - 如何设置 Spotify session 过期日期?