- 类,结构,枚举都可以定义下标脚本(subscripts),下标脚本是一种获取集合列表或序列的成员元素的快速方法。
- 使用下标脚本可以通过索引设置和获取值,而不需要设置和获取方法
- 你可以给一个类型定义多个下标脚本,合适的下标脚本将会根据你传给下标脚本的值的类型而被选中执行。下标脚本不一定只是一维的,你可以给下标脚本定义多个输入参数,以匹配你的类型的需求。
- subscript方法中,默认只实现了get方法,我们可以在其中添加set方法。
给一个类型定义多个下标
struct Vector1 {
var x: Double = 0.0
var y: Double = 0.0
var z: Double = 0.0
subscript(index: Int) -> Double? {
switch (index) {
case 0:
return x
case 1:
return y
case 2:
return z
default:
return nil
}
}
/// 下标不局限于Int类型
subscript(axis: String) -> Double? {
switch (axis) {
case "x", "X":
return x
case "y", "Y":
return y
case "z", "Z":
return z
default:
return nil
}
}
}
var vector1 = Vector1(x: 10, y: 20, z: 30)
// 可以通过下标来取值
vector1[0] // 10
vector1["Z"] // 30
下标支持set 和 get
struct Vector2 {
var x: Double = 0.0
var y: Double = 0.0
var z: Double = 0.0
subscript(index: Int) -> Double? {
get {
switch (index) {
case 0:
return x
case 1:
return y
case 2:
return z
default:
return nil
}
}
set {
guard let newValue = newValue else {return}
switch (index) {
case 0:
x = newValue
case 1:
y = newValue
case 2:
z = newValue
default:
break
}
}
}
}
var vector2 = Vector2(x: 10, y: 20, z: 30)
vector2[0] = 100
vector2 // x: 100, y: 20, z: 30
给String类添加下标扩展
extension String {
public subscript(start:Int, length:Int) -> String {
get {
let index1 = self.index(self.startIndex, offsetBy: start)
let index2 = self.index(index1, offsetBy: length)
let range = Range(uncheckedBounds: (lower: index1, upper: index2))
return String(self[range])
}
set {
let tmp = self
var s = ""
var e = ""
for (idx, item) in tmp.enumerated() {
if(idx < start) {
s += "\(item)"
}
if(idx >= start + length) {
e += "\(item)"
}
}
self = s + newValue + e
}
}
public subscript(index:Int) -> String {
get {
return String(self[self.index(self.startIndex, offsetBy: index)])
}
set {
let tmp = self
self = ""
for (idx, item) in tmp.enumerated() {
if idx == index {
self += "\(newValue)"
} else {
self += "\(item)"
}
}
}
}
}
var str = "abcdefg"
print(str[0,3]) // abc
print(str[2]) // a