1. 程式人生 > >Swift:下標

Swift:下標

下標選項

下標可以接收任意數量的輸入形式引數,並且這些輸入形式引數可以是任意型別。下標也可以返回任意型別。下標可以使用變數形式引數和可變形式引數,但是不能使用輸入輸出形式引數或提供預設形式引數值。

類或結構體可以根據自身需要提供多個下標實現,合適被使用的下標會基於值型別或者使用下標時下標方括號裡包含的值來推斷。這個對多下標的定義就是所謂的下標過載

通常來講下標接收一個形式引數,但只要你的型別需要也可以為下標定義多個引數。如下例定義了一個 Matrix 結構體,它呈現一個Double 型別的二維矩陣。 Matrix 結構體的下標接收兩個整數形式引數:

 

struct Matrix {

    let rows: Int, columns: Int

    var grid: [Double]

    init(rows: Int, columns: Int) {

        self.rows = rows

        self.columns = columns

        grid = Array(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), "Index out of range")

            return grid[(row * columns) + column]

        }

        set {

            assert(indexIsValid(row: row, column: column), "Index out of range")

            grid[(row * columns) + column] = newValue

        }

    }

}

Matrix 提供了一個接收 rows 和 columns 兩個形式引數的初始化器,建立了一個足夠容納 rows * columns 個數的 Double 型別陣列。矩陣裡的每個位置都用 0.0 初始化。要這麼做,陣列的長度,每一格初始化為 0.0 ,都傳入陣列初始化器來建立和初始化一個正確長度的陣列。這個初始化器在使用預設值建立陣列裡有更詳細的描述。

你可以通過傳入合適的行和列的數量來構造一個新的 Matrix 例項:

 

	
var matrix = Matrix(rows: 2, columns: 2)

上例中建立了一個新的兩行兩列的 Matrix 例項。 Matrix 例項中的陣列grid 是 矩陣的高效扁平化版本,閱讀順序從左上到右下:

subscriptMatrix01_2x

矩陣裡的值可以通過傳行和列給下標來設定,用逗號分隔:

 

matrix[0, 1] = 1.5

matrix[1, 0] = 3.2

上面兩條語句呼叫的下標的設定器來給矩陣的右上角( row 是 0 , column 是 1 )賦值為 1.5 ,給左下角( row 是 1 ,column 是 0 )賦值為 3.2 :

subscriptMatrix02_2x

 

Matrix 下標的設定器和讀取器都包含了一個斷言來檢查下標的 row 和 column 是否有效。為了方便進行斷言, Matrix 包含了一個名為 indexIsValidForRow(_:column:) 的成員方法,它用來確認請求的 row 或 column 值是否會造成陣列越界:

 

func indexIsValidForRow(row: Int, column: Int) -> Bool {

    return row >= 0 && row < rows && column >= 0 && column < columns

}

斷言在下標越界時觸發:

 

let someValue = matrix[2, 2]

// this triggers an assert, because [2, 2] is outside of the matrix bounds