「这是我参与11月更文挑战的第9天,活动详情查看:2021最后一次更文挑战」。
下标
下标定义了集合、列表或序列元素的快捷方式。它可以在类、结构和枚举中定义,以允许这样快速访问特定类型的元素。比如我们常用的Array、Dictionary、Set等标准 Swift 库都有它的身影。subscript === computed property(类似h5的计算属性。)
我们可以利用下标去获取某一个值:
var array = ["a", "b", "c"]
array[0]
var scores = [ "yuwen": 89, "shuxue": 90]
let score = scores["yuwen"]
也可以利用下标去创建一个值:
scores["yuwen"] = 91
如果没有下标的话,我们可能会通过数组或字典上定义的方法访问相同的值。这些方法很容易让你的代码看起来麻烦:
scores.set(92, forKey: "yuwen")
所以下标是用于访问集合的成员,它包含了如下特征:
- 包含集合的变量或常量,例如
scores - 一个[] 形式的包裹起来。
- 一个key或index在括号里面
scores["yuwen"] = 93
|
collection[key] = ···
同时下标不限于单个key或index,因此您也可以将它们用于多维嵌套数组和字典。如下面的二维数组:
let nums = [[10, 11], [13, 10]]
let value = nums[1][0]
自定义下标
可以使用subscript关键字定义自己的下标。这是一个可以添加到类、结构和枚举的函数。同时我们在设置下标的时候可以携带参数名标明语义。而且下标还可以进行读写操作,在通过添加 get 和 set 闭包,我们也可以轻松地实现读写的操作。
模板如下所示:
subscript(parameterList) -> ReturnType {
get {
// return someValue of ReturnType
}
set(newValue) {
// set someValue of ReturnType to newValue
}
}
struct 下标:
创建一个struct 下标的实例如下所示:
struct Course{
subscript(index: Int) -> String {
switch index {
case 0: return "语文"
case 1: return "数学"
case 2: return "英语"
default: return "体育"
}
}
}
enum 下标:
创建一个enum 下标的实例如下所示:
enum Course: Int {
case yuwen = 1, shuxue, yingyu
static subscript(n: Int) -> Planet {
return Course(rawValue: n)!
}
}
class 下标
创建一个class 下标的实例如下所示:
class File {
let name: String
init(name: String) {
self.name = name
}
// 1
subscript(key: String) -> String {
switch key {
case "path":
return "custom path"
default:
return "default path"
}
}
}
下标默认值
一般通过在第二个参数来为我们的下标提供一个默认值。使用@autoclosure用来避免评估默认值表达式。
extension UserDefaults {
struct Key<Value> {
var name: String
}
subscript<T>(
key: Key<T>,
default defaultProvider: @autoclosure () -> T
) -> T {
get {
return value(forKey: key.name) as? T
?? defaultProvider()
}
set {
setValue(newValue, forKey: key.name)
}
}
}
静态下标
静态下标 是Swift 在5.1 引入的一个新特性,它的工作方式与实例下标非常相似,但是它们使我们能够直接针对类型本身进行下标。
struct Stack {
static var stack: [Int] = [0, 1, 2, 3]
static subscript(index: Int) -> Int {
return stack[index]
}
}
但是需要注意的是静态下标 方法无法被覆盖!!!,所以当我们要使下标无法被覆盖可以使用静态下标,否则我们应该将其声明为实例下标或者类下标。。注意点:
static: 禁止覆盖!class:允许覆盖!