Swift 下标

192 阅读3分钟

「这是我参与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
  • 一个[] 形式的包裹起来。
  • 一个keyindex在括号里面
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:允许覆盖!