Swift-----下标(subscript)

  通常情况下,我们在使用数组(Array)、字典(Dictionary)时,都会使用下标。其实,在swift中,我们可以给类、结构体、枚举等自定义下标。

1 基本使用

struct Vector3 {
    
    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
        }
    }
    
    subscript(axis: String) -> Double? {
    
        switch (axis) {
        case "x", "X":
            return x
        case "y", "Y":
            return y
        case "z", "Z":
            return z
        default:
            return nil
        }
    }
    
}

  我们在结构体中定义了一个subscript,并且这个subscript类似于一个方法,看上去它的类型为 Int -> Double? , String -> Double?。然后在调用的时候,就可以使用"[index]","[string]"的形式取值。 

var vector = Vector3(x: 10, y: 20, z: 30)
// 可以通过下标来取值
vector[0]      // 10  
vector["Z"]    // 30

  以上代码中,我们只可以取值,但是不能使用"[index]","[string]"来赋值。

  以上subscript方法中,相当于只写了get方法,我们可以在其中添加set。这样就可以使用"[index]","[string]"来赋值了。

struct Vector3 {
    
    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:
                ()
            }
        }
    }
    
    subscript(axis: String) -> Double? {
    
        get {
            switch (axis) {
            case "x", "X":
                return x
            case "y", "Y":
                return y
            case "z", "Z":
                return z
            default:
                return nil
            }
        }
        
        set {
        
            guard let newValue = newValue else {return}
            
            switch (axis) {
            case "x", "X":
                x = newValue
            case "y", "Y":
                y = newValue
            case "z", "Z":
                z = newValue
            default:
                ()
            }
        }
    }
    
}

var vector = Vector3(x: 10, y: 20, z: 30)

vector[0] = 100
vector    // x: 100, y: 20, z: 30

vector["y"] = 200
vector   // x: 100, y: 200, z: 30

 2 多维下标

struct Matrix {
    
    var data: [[Double]]
    let row: Int
    let col: Int
    
    init (row: Int, col: Int) {
        
        self.row = row
        self.col = col
        
        data = [[Double]]()
        for _ in 0 ..< row {
            let arow = Array(repeating: 0.0, count: col)
            data.append(arow)
        }
    }
    
    subscript(x: Int, y: Int) -> Double {
    
        get {
            assert(x >= 0 && x < self.row && y >= 0 && y < self.col, "Index out of range.")
            return data[x][y]
        }
        
        set {
            assert(x >= 0 && x < self.row && y >= 0 && y < self.col, "Index out of range.")
            data[x][y] = newValue
        }
        
    }
    
    subscript(x: Int) -> [Double] {
    
        get {
            assert(x >= 0 && x < self.row, "Index out of range")
            return data[x]
        }
        
        set(vector) {
            assert(vector.count == self.col, "Column number does not match.")
            data[x] = vector
        }
    }
}

var matrix = Matrix(row: 2, col: 2)
matrix[1, 1]    // 0
matrix[1, 1] = 20 
matrix[1, 1]    // 20
matrix[0]      // [0, 0] matrix[1]      // [0, 20] matrix[0] = [10, 100] matrix[0]      // [10, 100] matrix[1]      // [0, 20]

matrix[0][0]    // 10
matrix[0][0] = 1000   
matrix[0][0]    // 1000

 

posted @ 2017-03-20 18:02  紫洁  阅读(1668)  评论(0编辑  收藏  举报