下标在Swift中允许以类似数组或字典的方式通过键或索引访问类型的值,但适用于任何自定义类型。语法类似于函数,但访问是通过括号实现的:object[key]。
特性:
get或同时包含get和set)。应用:
示例: 二维数组(矩阵)和具有两个参数的下标:
struct Matrix { let rows: Int, columns: Int private var grid: [Double] init(rows: Int, columns: Int) { self.rows = rows self.columns = columns grid = Array(repeating: 0.0, count: rows * columns) } subscript(row: Int, column: Int) -> Double { get { precondition(isValid(row: row, column: column), "索引超出范围") return grid[(row * columns) + column] } set { precondition(isValid(row: row, column: column), "索引超出范围") grid[(row * columns) + column] = newValue } } private func isValid(row: Int, column: Int) -> Bool { return row >= 0 && row < rows && column >= 0 && column < columns } } var matrix = Matrix(rows: 2, columns: 2) matrix[0,1] = 5.0 print(matrix[0,1]) // 5.0
下标是否可以具有类型为inout的参数或在结构体中是mutating的?
回答:
inout。mutating set,这允许在set内修改self:struct Counter { var value: Int = 0 subscript(increment: Bool) -> Int { mutating get { value += increment ? 1 : -1 return value } } }
故事
在自定义集合中忘记将下标设置为mutating,因此通过下标修改元素的任何尝试都会导致编译错误。错误在经过长时间调试后,在集成集合的阶段显现出来。
故事
在自定义下标中未实现对索引越界的正确处理,这导致在超出范围访问时崩溃。因此,影响到了业务关键的数据处理功能。
故事
在枚举中实现了具有两个参数的下标用于缓存,但未考虑到下标不能是static(类型级别的),只能是实例级别的。架构决策被证明是错误的,不得不重写集合的API交互。