编程iOS/Swift 开发者

解释一下 Swift 中的下标是如何工作的,它的声明和调用规则,以及它与普通方法或计算属性的区别?

用 Hintsage AI 助手通过面试

回答。

问题的背景:

下标是在 Swift 中引入的,以方便和安全地操作集合和数据结构,允许使用熟悉的方括号语法访问元素。

问题:

下标、方法和计算属性之间的混淆,它们的应用范围,以及错误地将下标用于访问不是集合的数据或具有副作用的数据。

解决方案:

下标是一种特殊机制,允许通过方括号提供对对象元素的访问。可以是只读的或读写的,并支持任何类型的参数:不仅仅是 Int,还支持 String 或自定义类型。

代码示例:

struct Matrix { private var data: [[Int]] init(rows: Int, columns: Int) { data = Array(repeating: Array(repeating: 0, count: columns), count: rows) } subscript(row: Int, column: Int) -> Int { get { data[row][column] } set { data[row][column] = newValue } } } var matrix = Matrix(rows: 2, columns: 2) matrix[0, 1] = 5 print(matrix[0, 1]) // 5

关键特性:

  • 允许根据需要重载(overload)下标,包括使用不同参数的多个下标。
  • 与方法不同,下标总是通过方括号调用。
  • 可以返回任何类型的值,支持读取和写入。

具有陷阱的问题。

下标可以有多个参数吗?

是的,下标可以接受任何参数集和任何类型(例如,元组)。

代码示例:

// 请参见上面的 Matrix 示例,其中下标为 (row: Int, column: Int)

是否可以实现只读(read-only)的下标?

是的,如果不声明 set,下标将是只读的。

代码示例:

struct ReadOnlyArray { private let items = [1, 2, 3] subscript(index: Int) -> Int { return items[index] } }

下标和计算属性之间有什么区别?

计算属性始终有固定的名称,并且不接受参数。下标允许通过可变索引访问,模拟集合结构。

常见错误和反模式

  • 使用下标进行具有副作用的操作(例如,修改全局变量)。
  • 隐式处理索引越界(崩溃而不是安全行为)。
  • 在没有明显原因的情况下混淆下标和方法。

生活中的例子

负面案例

在自定义结构中,下标用于更改全局状态,这在简单访问数组中的元素时会导致意想不到的副作用。

优点:

  • 简洁

缺点:

  • 不明显的副作用
  • 难以调试

正面案例

下标仅用于处理结构内部的私有数组,已实现越界处理并返回 nil。

优点:

  • 合理且安全
  • 易于调试
  • 代码易于阅读

缺点:

  • 如有必要,需要添加显式错误处理