質問の歴史:
サブスクリプトは、コレクションやデータ構造と安全に便利に操作するためにSwiftに導入され、コーナーブラケットの構文を使用して要素にアクセスできるようにします。
問題:
サブスクリプト、メソッド、計算型プロパティの混同及びそれらの適用範囲、コレクションでないデータへのアクセスや副作用のあるデータへの誤ったサブスクリプトの使用。
解決策:
サブスクリプトは、コーナーブラケットを使用してオブジェクトの要素へのアクセスを提供する特別なメカニズムです。読み取り専用または読み書き可能であり、IntだけでなくStringや独自の型など、あらゆる種類のパラメータをサポートします。
コードの例:
struct Matrix { private var data: [[Int]] init(rows: Int, columns: Int) { data = Array(repeating: Array(repeating: 0, count: columns), count: rows) } subscript(row: Int, column: Int) -> Int { get { data[row][column] } set { data[row][column] = newValue } } } var matrix = Matrix(rows: 2, columns: 2) matrix[0, 1] = 5 print(matrix[0, 1]) // 5
主要な特徴:
サブスクリプトは複数のパラメータを持てますか?
はい、サブスクリプトは任意のパラメータのセットと任意の型(例えば、タプル)を受け取ることができます。
コードの例:
// 上記のMatrixの例を参照してください (サブスクリプト(row: Int, column: Int))
読み取り専用のサブスクリプトを実装できますか?
はい、setを宣言しなければ、サブスクリプトは読み取り専用となります。
コードの例:
struct ReadOnlyArray { private let items = [1, 2, 3] subscript(index: Int) -> Int { return items[index] } }
サブスクリプトと計算型プロパティの違いは何ですか?
計算型プロパティは常に固定名を持ち、パラメータを受け取ることはありません。サブスクリプトは可変インデックスでアクセスすることができ、コレクション構造を模倣します。
カスタム構造体でサブスクリプトがグローバル状態を変更するために使用され、配列内の要素に簡単にアクセスしただけで想定外の副作用を引き起こす。
利点:
欠点:
サブスクリプトは、構造体内部のプライベート配列と連携するためのみに使用され、範囲外へのアクセスにはnilを返す処理が実装されています。
利点:
欠点: