Swift下标脚本全解析
·
Swift 下标脚本基础概念
下标脚本(Subscripts)是 Swift 中一种特殊语法,允许通过索引或键值快速访问集合、列表或自定义类型的元素。下标脚本可以定义为实例方法或类型方法,语法类似于计算属性。
struct Matrix {
let rows: Int, columns: Int
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 {
return grid[(row * columns) + column]
}
set {
grid[(row * columns) + column] = newValue
}
}
}
var matrix = Matrix(rows: 2, columns: 2)
matrix[0, 1] = 1.5 // 调用下标脚本的 setter
print(matrix[0, 1]) // 输出: 1.5
多维下标脚本实现
下标脚本支持多参数,适用于多维数据结构。以下示例展示了一个三维数组的下标脚本实现:
struct ThreeDArray {
var data: [[[Int]]]
init(x: Int, y: Int, z: Int) {
data = Array(repeating: Array(repeating: Array(repeating: 0, count: z), count: y), count: x)
}
subscript(x: Int, y: Int, z: Int) -> Int {
get { return data[x][y][z] }
set { data[x][y][z] = newValue }
}
}
var array3D = ThreeDArray(x: 2, y: 2, z: 2)
array3D[1, 0, 1] = 42
print(array3D[1, 0, 1]) // 输出: 42
类型下标脚本(静态下标)
Swift 5.1 引入了类型下标脚本(static subscript),允许通过类型本身而非实例访问下标:
enum Planet: Int {
case mercury = 1, venus, earth, mars
static subscript(n: Int) -> Planet? {
return Planet(rawValue: n)
}
}
let planet = Planet[3] // 返回 Optional(Planet.earth)
print(planet!) // 输出: earth
下标脚本重载
同一个类型可以定义多个下标脚本,通过参数类型或数量区分。以下示例展示字符串通过整型索引或范围访问子串:
extension String {
subscript(index: Int) -> Character {
return self[self.index(startIndex, offsetBy: index)]
}
subscript(range: Range<Int>) -> Substring {
let start = index(startIndex, offsetBy: range.lowerBound)
let end = index(startIndex, offsetBy: range.upperBound)
return self[start..<end]
}
}
let str = "Swift"
print(str[2]) // 输出: i
print(str[1..<4]) // 输出: wif
下标脚本与泛型结合
下标脚本可以结合泛型实现更灵活的访问逻辑。以下示例展示了一个泛型栈的下标脚本实现:
struct Stack<Element> {
private var elements = [Element]()
mutating func push(_ element: Element) {
elements.append(element)
}
mutating func pop() -> Element? {
return elements.popLast()
}
subscript(index: Int) -> Element? {
guard index < elements.count else { return nil }
return elements[index]
}
}
var stack = Stack<String>()
stack.push("Apple")
stack.push("Banana")
print(stack[1]!) // 输出: Banana
下标脚本的最佳实践
- 明确用途:下标脚本应专注于简化数据访问,避免包含复杂业务逻辑。
- 参数命名:使用
row、column等语义化参数名提升可读性。 - 错误处理:通过返回可选值或断言处理无效索引,避免崩溃。
struct SafeArray<T> {
private var array: [T]
init(_ array: [T]) {
self.array = array
}
subscript(index: Int) -> T? {
return index < array.count ? array[index] : nil
}
}
let safeArray = SafeArray([1, 2, 3])
print(safeArray[5] ?? "Index out of bounds") // 输出: Index out of bounds
更多推荐
所有评论(0)