は 100 を 2 で割ったものです。

サブスクリプトは、クラス、構造体、列挙型などのターゲットに定義でき、オブジェクト、コレクション、またはシーケンスにアクセスするためのショートカットと考えることができます。インスタンスの特定の代入メソッドやアクセスメソッドを呼び出す必要はありません。

例えば、サブスクリプトを使って配列(Array)インスタンスの要素にアクセスするには someArray[index] のように書き、辞書(Dictionary)インスタンスの要素にアクセスするには someDictionary[key] のように書きます。

同じターゲットに対して複数のサブスクリプトを定義でき、インデックス値の型の違いによってオーバーロードでき、インデックス値の数も複数にすることができます。


サブスクリプトの構文と応用

構文

サブスクリプトを使用すると、インスタンスの後ろの角括弧内に1つ以上のインデックス値を渡すことで、インスタンスにアクセスして値を代入できます。

構文はインスタンスメソッドと計算プロパティを混ぜたようなものです。

インスタンスメソッドの定義と同様に、サブスクリプトの定義には subscript キーワードを使用し、入引数(1つまたは複数)と戻り値の型を明示的に宣言します。

インスタンスメソッドとは異なり、サブスクリプトは読み書き可能または読み取り専用に設定できます。この方法は計算プロパティの getter と setter に少し似ています:

subscript(index: Int) -> Int {
    get {
        // 用于下标脚本值的声明
    }
    set(newValue) {
        // 执行赋值操作
    }
}

例 1

import Cocoa

struct subexample {
    let decrementer: Int
    subscript(index: Int) -> Int {
        return decrementer / index
    }
}
let division = subexample(decrementer: 100)

print("100 除以 9 等于 \(division[9])")
print("100 除以 2 等于 \(division[2])")
print("100 除以 3 等于 \(division[3])")
print("100 除以 5 等于 \(division[5])")
print("100 除以 7 等于 \(division[7])")

上記のプログラムを実行すると、出力結果は次のようになります:

100 除以 9 等于 11
100 除以 2 等于 50
100 除以 3 等于 33
100 除以 5 等于 20
100 除以 7 等于 14

上記の例では、subexample 構造体を通じて除算演算のインスタンスを作成しました。数値 100 が構造体のコンストラクタの引数として渡され、インスタンスメンバー decrementer を初期化します。

サブスクリプトを使用して結果を取得できます。例えば、division

例 2

import Cocoa

class daysofaweek {
    private var days = ["Sunday", "Monday", "Tuesday", "Wednesday",
        "Thursday", "Friday", "saturday"]
    subscript(index: Int) -> String {
        get {
            return days[index]   // 声明下标脚本的值
        }
        set(newValue) {
            self.days[index] = newValue   // 执行赋值操作
        }
    }
}
var p = daysofaweek()

print(p[0])
print(p[1])
print(p[2])
print(p[3])

上記のプログラムを実行すると、出力結果は次のようになります:

Sunday
Monday
Tuesday
Wednesday

使い方

使用シーンに応じて、サブスクリプトも異なる意味を持ちます。

通常、サブスクリプトはコレクション、リスト、またはシーケンス内の要素にアクセスするためのショートカットです。

独自の特定のクラスや構造体の中で、サブスクリプトを自由に実装して適切な機能を提供できます。

例えば、Swift の辞書(Dictionary)は、サブスクリプトを使用してインスタンスに格納されている値にアクセス・格納する操作を実装しています。サブスクリプトでは辞書のインデックスと同じ型の値を使用し、辞書の値の型の値をこのサブスクリプトに代入して辞書に値を設定します:

import Cocoa

var numberOfLegs = ["spider": 8, "ant": 6, "cat": 4]
numberOfLegs["bird"] = 2

print(numberOfLegs)

上記のプログラムを実行すると、出力結果は次のようになります:

["ant": 6, "bird": 2, "cat": 4, "spider": 8]

上記の例では、numberOfLegs という名前の変数を定義し、辞書リテラルを使用して3組のキーと値を含む辞書インスタンスを初期化しています。numberOfLegs の辞書に格納される値の型は Dictionary と推論されます。辞書インスタンスの作成が完了した後、サブスクリプトを使用して、整数値 2 を辞書インスタンスのインデックスが bird の位置に代入します。


サブスクリプトのオプション

サブスクリプトは任意の数の引数インデックスを許可し、各引数の型にも制限はありません。

サブスクリプトの戻り値も任意の型にできます。

サブスクリプトは変数パラメータと可変長パラメータを使用できます。

クラスや構造体は、自身のニーズに応じて複数のサブスクリプト実装を提供でき、サブスクリプトを定義する際に渡されるパラメータの型によって区別されます。サブスクリプトを使用すると、適切なサブスクリプト実装が自動的に選択されて実行されます。これがサブスクリプトのオーバーロードです。。

import Cocoa

struct Matrix {
    let rows: Int, columns: Int
    var print: [Double]
    init(rows: Int, columns: Int) {
        self.rows = rows
        self.columns = columns
        print = Array(repeating: 0.0, count: rows * columns)
    }
    subscript(row: Int, column: Int) -> Double {
        get {
            return print[(row * columns) + column]
        }
        set {
            print[(row * columns) + column] = newValue
        }
    }
}
// 创建了一个新的 3 行 3 列的Matrix实例
var mat = Matrix(rows: 3, columns: 3)

// 通过下标脚本设置值
mat[0,0] = 1.0
mat[0,1] = 2.0
mat[1,0] = 3.0
mat[1,1] = 5.0

// 通过下标脚本获取值
print("\(mat[0,0])")
print("\(mat[0,1])")
print("\(mat[1,0])")
print("\(mat[1,1])")

上記のプログラムを実行すると、出力結果は次のようになります:

1.0
2.0
3.0
5.0

Matrix 構造体は、2つの引数 rows と columns を受け取るコンストラクタを提供しており、rows * columns 個の Double 型の値を格納できる配列を作成します。格納するために、配列のサイズを rows * columns に設定し、各要素の初期値を 0.0 にします。

適切な row と column の数を渡すことで、新しい Matrix インスタンスを構築できます。

その他の拡張