標籤:color sel == guard data rip efault 方法 code
通常情況下,我們在使用數組(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] = 100vector // x: 100, y: 20, z: 30vector["y"] = 200vector // 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] // 0matrix[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
Swift-----下標(subscript)