加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

Swift下标

发布时间:2020-12-14 06:09:00 所属栏目:百科 来源:网络整理
导读:Swift下标 参考: Implementing Custom Subscripts in Swift 下标 定义下标: subscript (parameterList) - ReturnType { get { // return someValue of ReturnType } set (newValue) { // set someValue of ReturnType to newValue }} Subscript 的定义混合

Swift下标

参考:

  • Implementing Custom Subscripts in Swift

下标

定义下标:

subscript(parameterList) -> ReturnType {
  get {
    // return someValue of ReturnType
  }

  set (newValue) {
    // set someValue of ReturnType to newValue
  }
}

Subscript的定义混合了function和计算属性的语法:
1.第一部分类似于一个函数的定义,有参数和返回值。使用subscript关键字,而不是使用func关键字和函数名称
2.主体部分类似计算属性,带有gettersetter

基础

对于数组,可以通过下标来获取到数组的元素,如

var arr = [0,1,2,3] arr[1]

同理对于字典也是一样的,只是要通过key来获取键对应的值

除此之外,在Swift中还可以为自己创建的任何类型,如枚举、结构体、类创建下标

如下一个结构体Vector3,表示三维向量:

struct Vector3{
    var x: Double = 0.0
    var y: Double = 0.0
    var z: Double = 0.0
}

var v = Vector3(x: 1.0,y: 2.0,z: 3.0)

对于结构体,我们可以通过v.x的形式来获取相应分量的值。但如果想通过v[0]这种形式来获取分量的值该怎么办呢?

要引入subscript关键字,可以把subscript理解为一个特殊的函数,这个函数需要一个参数,并且要有一个返回值。如下,已整型作为参数类型,返回一个浮点型:

subscript(index: Int) -> Double?{
        switch index{
        case 0: return x
        case 1: return y
        case 2: return z
        default: return nil
        }
    }

这样实现之后,就可以通过v[0]来获取分量的值了

在一个枚举、类中可以有多个下标的方法。如下,通过字符串来访问Vector3的分量的值:

subscript(axis: String) -> Double?{
        switch axis{
        case "x","X": return x
        case "y","Y": return y
        case "z","Z": return z
        default: return nil
        }
    }

此时就可以通过v["z"]来访问z轴分量的值了

现在我们只是通过下标来读取数据,那怎样通过下标来改变数值呢?

计算属性有gettersetter,对下标而言也一样,如下:

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: return
            }
        }
    }

这里的newValue的类型是Double?(与subscript的返回值类型是一致的),所以在设置值的时候要解包

这样设置之后,就可以通过v[1] = 100.0这种形式来设置分量的值了

多维下标

上面讲的都是一个参数的下标,实际上swift语言支持有任意多个参数的下标

如下的一个结构体矩阵Matrix

struct Matrix{
    var data: [[Double]]
    let r:Int
    let c:Int

    init(row: Int,col: Int) {
        self.r = row
        self.c = col
        data = [[Double]]()
        for _ in 0..<r {
            let aRow = [Double](repeating: 0.0,count: col)
            data.append(aRow)
        }
    }
}

如下的初始化方法,创建value都为0.0的矩阵

var m = Matrix(row: 2,col: 2)

那如何通过下标来访问矩阵中的元素呢?同上面一样,也是使用subscript。这里有两个参数,返回值为Double

subscript(x:Int,y:Int)->Double{
        assert(x>=0&&x<r&&y>=0&&y<c,"Index out of range")
        return data[x][y]
    }

这里使用了断言,因为数组越界会出错
此时通过m[1,1]就可以得到矩阵在1,1,这个位置的元素。注意不是使用m[1][1]

上面的添加的只是获取元素的方法,现添加上set方法

subscript(x:Int,y:Int)->Double{
        get{
            assert(x>=0&&x<r&&y>=0&&y<c,"Index out of range")
            return data[x][y]
        }
        set{
            assert(x>=0&&x<r&&y>=0&&y<c,"Index out of range")
            data[x][y] = newValue
        }
    }

就可以通过m[1,0] = 2.0来设置值了

但是,通常一般是通过m[1][1]来获矩阵取值,为支持这种形式,再创建一个subscript。这个时候只有一个参数,返回值类型为[Double]

subscript(row: Int)->[Double]{
        get{
            assert(row>=0&&row<r,"Index out of range")
            return data[row]
        }
        set(vector){
            assert(vector.count == c,"column number does not match")
            data[row] = vector
        }
    }

此时,就可以通过m[1][1]形式获取值,通过m[0] = [1.5,4.5]形式设置值了

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读