Menu

Category

Archive

logo


The Swift Programming Language ~ Subscripts

2014-06-18 22:00:00 +0900
  • このエントリーをはてなブックマークに追加

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 subscript(index: Int) -> Int {
2     get {
3         // return an appropriate subscript value here
4     }
5     set(newValue) {
6         // perform a suitable setting action here
7     }
8 }

読み込み専用の Subscripts を定義する場合には、get を省略できます。このコードは、Subscripts の引数として Int を取り、それと構造体のプロパティの掛け算の結果を返す読み込み専用の Subscripts です。

1 struct TimesTable {
2     let multiplier: Int
3     subscript(index: Int) -> Int {
4         return multiplier * index
5     }
6 }
7 let threeTimesTable = TimesTable(multiplier: 3)
8 println("six times three is \(threeTimesTable[6])")
9 // prints "six times three is 18

2. More Subscripts

Subscripts は、いくつでも引数を取ることができます。また、これらの引数はどんなデータ型でも大丈夫です。また、どんなデータ型でも返り値になれます。さらに、可変引数の Subscripts も定義できます。しかし、in-out 引数は使えませんし、引数にデフォルト値を持たせることもできません。

 1 struct Matrix {
 2     let rows: Int, columns: Int
 3     var grid: Double[]
 4     init(rows: Int, columns: Int) {
 5         self.rows = rows
 6         self.columns = columns
 7         grid = Array(count: rows * columns, repeatedValue: 0.0)
 8     }
 9     func indexIsValidForRow(row: Int, column: Int) -> Bool {
10         return row >= 0 && row < rows && column >= 0 && column < columns
11     }
12     subscript(row: Int, column: Int) -> Double {
13         get {
14             assert(indexIsValidForRow(row, column: column), "Index out of range")
15             return grid[(row * columns) + column]
16         }
17         set {
18             assert(indexIsValidForRow(row, column: column), "Index out of range")
19             grid[(row * columns) + column] = newValue
20         }
21     }
22 }
23 
24 // Usage
25 var matrix = Matrix(rows: 2, columns: 2)
26 matrix[0, 1] = 1.5
27 matrix[1, 0] = 3.2
28 let someValue = matrix[2, 2]
29 // this triggers an assert, because [2, 2] is outside of the matrix bounds

この Matrix 構造体の例では、引数を 2 つ取る Subscripts を使い、Matrix の要素のゲッターセッターを実装しています。