下标(subscript)
使用subscript可以给任意类型(枚举、结构体、类)增加下标功能,有些地方也翻译为:下标脚本
subscript的语法类似于实例方法、计算属性,本质就是方法(函数)
class Point {
var x: Double = 0
var y: Double = 0
subscript(index: Int) -> Double {
set {
if index == 0 {
x = newValue
} else if index == 1 {
y = newValue
}
}
get {
if index == 0 {
return x
} else if index == 1 {
return y
}
return 0
}
}
}
let point = Point()
point[0] = 1
point[1] = 2
let x = point[0]
let y = point[1]
print(x, y) // 1.0 2.0
给point添加下标,point[0]就是给x赋值,point[1]就是给y赋值。
subscript中定义的返回值类型决定了:
- get方法的返回值类型
- set方法中的newValue的类型
下标的细节
1、subscript可以没有set方法,但必须要有get方法
class Point {
var x: Double = 0
var y: Double = 0
subscript(index: Int) -> Double {
get {
if index == 0 {
return x
} else if index == 1 {
return y
}
return 0
}
}
}
2、如果只有get方法,可以省略get
class Point {
var x: Double = 0
var y: Double = 0
subscript(index: Int) -> Double {
if index == 0 {
return x
} else if index == 1 {
return y
}
return 0
}
}
3、可以设置参数标签
class Point {
var x: Double = 0
var y: Double = 0
subscript(index i: Int) -> Double {
if i == 0 {
return x
} else if i == 1 {
return y
}
return 0
}
}
var p = Point()
print(p[index: 0], p[index: 1]) // 0.0 0.0
添加参数标签后,使用下标时,需要书写参数标签。
4、下标可以是类型方法
class Sum {
static subscript(v1: Int, v2: Int) -> Int {
v1 + v2
}
}
print(Sum[10, 20]) // 30
结构体、类作为返回值对比
struct Point {
var x = 1, y = 2
}
class PointManager {
var point = Point()
subscript(index: Int) -> Point {
set { point = newValue}
get { point }
}
}
var pm = PointManager()
pm[0].x = 10
pm[0].y = 20
print(pm[0].x, pm[0].y) // 10 20
pm[0].x = 10这行代码,在外部传入的时int类型的数据,但是set方法里接收的是point类型,原因是pm[0].x = 10相当于:
pm[0] = Point(x: 10, y: pm[0].y)
如果Point是类,可以省略下标中的get方法:
class Point {
var x = 1, y = 2
}
class PointManager {
var point = Point()
subscript(index: Int) -> Point {
get { point }
}
}
var pm = PointManager()
pm[0].x = 10
pm[0].y = 20
print(pm[0].x, pm[0].y)
原因是类是引用类型,get方法返回的是指针,所以可以直接修改对应的x和y的值。
接收多个参数的下标
class Grid {
var data = [
[0, 1, 2],
[3, 4, 5],
[6, 7, 8]
]
subscript(row: Int, column: Int) -> Int {
set {
guard row >= 0 && row <= 3 && column >= 0 && column <= 3 else {
return
}
data[row][column] = newValue
}
get {
guard row >= 0 && row <= 3 && column >= 0 && column <= 3 else {
return 0
}
return data[row][column]
}
}
}
var grid = Grid()
grid[0, 1] = 111
grid[1, 0] = 222
grid[2, 2] = 333
print(grid.data)
打印结果:
[[0, 111, 2], [222, 4, 5], [6, 7, 333]]