iBooks にある “The Swift Programming Language” の勉強メモ。Objective-C と C を普段書いている自分から、ちょっと馴染みがないものを特にまとめておきます。目次は こちら。
今回は、Subscripts に関して。
Subscripts
Subscripts は、配列や Dictionary といったデータ構造に対して、そのデータにアクセスするための記述方法です。Dictionary であれば、dict[“Kazuya”] のようなものです。実際に、Swift の Dictionary はこの方法で実装されているようです。Swift では、この Subscripts をクラス・構造体・Enumeration に対して定義することもできます。
1. Subscripts Syntax
あるタイプに新しく Subscripts を定義するには、subscript
キーワードを使用します。そして、インスタンスメソッドのように、引数と返り値を指定します。読み込み専用か読み書き可能の Subscripts を定義することができます。
1 2 3 4 5 6 7 8 | subscript(index: Int) -> Int { get { // return an appropriate subscript value here } set(newValue) { // perform a suitable setting action here } } |
読み込み専用の Subscripts を定義する場合には、get
を省略できます。このコードは、Subscripts の引数として Int を取り、それと構造体のプロパティの掛け算の結果を返す読み込み専用の Subscripts です。
1 2 3 4 5 6 7 8 9 | struct TimesTable { let multiplier: Int subscript(index: Int) -> Int { return multiplier * index } } let threeTimesTable = TimesTable(multiplier: 3) println("six times three is \(threeTimesTable[6])") // prints "six times three is 18 |
2. More Subscripts
Subscripts は、いくつでも引数を取ることができます。また、これらの引数はどんなデータ型でも大丈夫です。また、どんなデータ型でも返り値になれます。さらに、可変引数の Subscripts も定義できます。しかし、in-out
引数は使えませんし、引数にデフォルト値を持たせることもできません。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 | struct Matrix { let rows: Int, columns: Int var grid: Double[] init(rows: Int, columns: Int) { self.rows = rows self.columns = columns grid = Array(count: rows * columns, repeatedValue: 0.0) } func indexIsValidForRow(row: Int, column: Int) -> Bool { return row >= 0 && row < rows && column >= 0 && column < columns } subscript(row: Int, column: Int) -> Double { get { assert(indexIsValidForRow(row, column: column), "Index out of range") return grid[(row * columns) + column] } set { assert(indexIsValidForRow(row, column: column), "Index out of range") grid[(row * columns) + column] = newValue } } } // Usage var matrix = Matrix(rows: 2, columns: 2) matrix[0, 1] = 1.5 matrix[1, 0] = 3.2 let someValue = matrix[2, 2] // this triggers an assert, because [2, 2] is outside of the matrix bounds |
この Matrix 構造体の例では、引数を 2 つ取る Subscripts を使い、Matrix の要素のゲッターセッターを実装しています。