阅读 299

Swift 5.1 (12) - 下标

级别: ★☆☆☆☆
标签:「iOS」「Swift 5.1」「下标」
作者: 沐灵洛
审校: QiShare团队


下标

下标是一种用于访问集合,列表或序列中元素的快捷方式。当我们获取或设置某个类型的成员元素的值时,可以使用下标通过索引去设置和检索其对应的元素值,而不需要单独的方法。

下标语法

subscript关键字表示下标的定义,在subscript后指定下标方法调用所需参数和返回类型。和实例方法的定义方式相同。但是下标支持对实例属性的读写或只读,此行为和计算属性一样需要借助gettersetter。下标可以让我们通过在类型实例后的方括号中写入一个或多个参数值来进行查询和设置操作。
读写下标的声明:

subscript(index : Int)->Int{
    get {
        /* return 整数类型的值*/
    }
    set {
        /*进行设置操作*/
    }
}
复制代码

只读下标声明:

subscript(index : Int)->Int{
    get {
        /* return 整数类型的值*/
    }
}
复制代码

只读下标的声明与只读计算属性一样,可以通过删除get关键字及其大括号来进行简化:

subscript(index : Int)->Int{
     /* return 整数类型的值*/
}
复制代码

下标使用

关于下标的使用,大多数情况下,单个参数的下标形式最为常见。但在合适的场景下,下标可以使用任意数量,任意类型的输入参数,同时也可以返回任何类型的实例作为返回值。下标的参数可以使用提供默认值的可变参数,但不能使用输入输出参数inout
下标的重载:类或结构体可以根据需要提供多个下标的实现(名称一致,参数不一致或返回值不一致)。同一个类或结构体中定义多个下标实现的形式称为下标的重载。
使用举例:定义一个二维矩阵Matrix的结构体,并实现使用下标使得Matrix可以按照行,列来获取和设置矩阵中的值。

struct Matrix {
    var description: String{
        var line = 0
        var desStr = ""
        for item in matrixArray.enumerated() {
            if item.0 / columns == line {
                desStr += "|" + String(item.1) + ""
            } else {
                line = item.0 / columns
                desStr += "|"
                //换行符
                desStr += "\n" + "|" + String(item.1)
            }
        }
        return "输出的矩阵为:"+"\n"+desStr + "|"
    }
    let rows : Int,columns : Int
    var matrixArray : [Double]
    init(rows:Int,columns : Int) {
        self.rows = rows
        self.columns = columns
        matrixArray = Array.init(repeating: 0.0, count: rows * columns)
    }
    func indexIsValid(row: Int, column: Int) -> Bool {
        return row >= 0 && row < rows && column >= 0 && column < columns
    }
    //! 获取和设置矩阵相应位置的元素
    subscript(row:Int,column:Int)->Double {
        get {
            
            assert(indexIsValid(row: row, column: column), "行或者列的下标超出了矩阵的边界")
            return matrixArray[row * columns + columns]
        }
        set {
            assert(indexIsValid(row: row, column: column), "行或者列的下标超出了矩阵的边界")
            matrixArray[row * columns + column] = newValue
        }
    }
    //! 重载`Matrix`的下标:定义系数设置时累积
    subscript(row:Int,column:Int,factor:Double)->Double{
        get {
            assert(indexIsValid(row: row, column: column), "行或者列的下标超出了矩阵的边界")
            return matrixArray[row * columns + columns]
        }
        set {
            assert(indexIsValid(row: row, column: column), "行或者列的下标超出了矩阵的边界")
            matrixArray[row * columns + column] = newValue * factor
        }
    }
    
}
复制代码

调用方式与结果打印

var matrix = Matrix.init(rows: 3, columns: 3)
print(matrix.description)
/*
 输出的矩阵为:
 |0.0|0.0|0.0|
 |0.0|0.0|0.0|
 |0.0|0.0|0.0|
 */

matrix[2,2] = 3.8 //!< 修改第2行第2列的元素为3.8
print(matrix.description)
/*
 输出的矩阵为:
 |0.0|0.0|0.0|
 |0.0|0.0|0.0|
 |0.0|0.0|3.8|
 */
matrix[1,1] = 6.0 //!< 修改第1行第1列的元素为6.0
print(matrix.description)
/*
 输出的矩阵为:
 |0.0|0.0|0.0|
 |0.0|6.0|0.0|
 |0.0|0.0|3.8|
 */
matrix[0,0,2.0] = 4.5
print(matrix.description)
/*
 输出的矩阵为:
 |9.0|0.0|0.0|
 |0.0|6.0|0.0|
 |0.0|0.0|3.8|
 */
复制代码

类型下标

实例下标是在特定类型的实例上调用的下标。同时我们也可以定义类型下标,类型下标:定义在类型本身上的下标。
方式:通过在subscript关键字之前写static关键字来表示类型下标。类可以使用class关键字,以允许子类覆盖父类中该下标的实现。事实证明在Swift 5.1中类型下标是不被允许的。

参考资料: swift 5.1官方编程指南


小编微信:可加并拉入《QiShare技术交流群》。

关注我们的途径有:
QiShare(简书)
QiShare(掘金)
QiShare(知乎)
QiShare(GitHub)
QiShare(CocoaChina)
QiShare(StackOverflow)
QiShare(微信公众号)

推荐文章:
今天我们来聊一聊WebSocket(iOS/Golang)
用 Swift 进行贝塞尔曲线绘制
Swift 5.1 (11) - 方法
Swift 5.1 (10) - 属性
iOS App后台保活
奇舞周刊

关注下面的标签,发现更多相似文章
评论